Как отключить все виды внутри макета?
Например, у меня есть:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/backbutton"
android:text="Back"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/my_layout"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/my_text_view"
android:text="First Name"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/my_edit_view"
android:width="100px"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<View .../>
<View .../>
...
<View .../>
</LinearLayout>
</LinearLayout>
Есть ли способ отключить (setEnable (false)) все элементы внутри LinearLayout my_layout
?
Ответы
Ответ 1
Другой способ - вызвать setEnabled() для каждого дочернего элемента (например, если вы хотите выполнить дополнительную проверку на дочернем элементе перед отключением)
LinearLayout layout = (LinearLayout) findViewById(R.id.my_layout);
for (int i = 0; i < layout.getChildCount(); i++) {
View child = layout.getChildAt(i);
child.setEnabled(false);
}
Ответ 2
этот рекурсивный для ViewGroups
private void disableEnableControls(boolean enable, ViewGroup vg){
for (int i = 0; i < vg.getChildCount(); i++){
View child = vg.getChildAt(i);
child.setEnabled(enable);
if (child instanceof ViewGroup){
disableEnableControls(enable, (ViewGroup)child);
}
}
}
Ответ 3
Ответ на туту на правильном пути, но его рекурсия немного неудобна. Я думаю, что это чище:
private static void setViewAndChildrenEnabled(View view, boolean enabled) {
view.setEnabled(enabled);
if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) view;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
View child = viewGroup.getChildAt(i);
setViewAndChildrenEnabled(child, enabled);
}
}
}
Ответ 4
В действительности, какая работа для меня:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
и отменить его:
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
Ответ 5
Изменить код tütü
private void disableEnableControls(boolean enable, ViewGroup vg){
for (int i = 0; i < vg.getChildCount(); i++){
View child = vg.getChildAt(i);
if (child instanceof ViewGroup){
disableEnableControls(enable, (ViewGroup)child);
} else {
child.setEnabled(enable);
}
}
}
Я думаю, нет смысла просто отключать отображение группы. Если вы хотите это сделать, есть другой способ, который я использовал для той же цели. Создайте представление в качестве родного брата вашего группового просмотра:
<View
android:visibility="gone"
android:id="@+id/reservation_second_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:background="#66ffffff"
android:clickable="false" />
и во время выполнения сделайте его видимым. Примечание. Родительский макет группового представления должен быть либо относительным, либо макетом. Надеюсь, это поможет.
Ответ 6
Если какой-то отчаянный разработчик прокручивается здесь, у меня есть еще один вариант сделать это. Который также отключает прокрутку, насколько я экспериментировал с ней. Идея состоит в том, чтобы использовать элемент View, подобный этому, в RelativeLayout, под всеми вашими элементами пользовательского интерфейса.
<View
android:id="@+id/shade"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/primaryShadow"
android:visibility="gone"/>
Поэтому он должен быть "ушел" перед некоторым условием. И затем вы установите его видимость для VISIBLE, когда вы хотите отключить свой интерфейс. Также вы должны реализовать OnClickListener
для этого представления. Этот OnClickListener
будет захватывать событие click и не будет передавать его базовым элементам.
Ответ 7
Если вы заинтересованы в отключении представлений в определенной ViewGroup, то вы можете использовать интересный, возможно, немного неясный duplicateParentState
. Состояние просмотра - это набор логических атрибутов, таких как нажатие, включение, активация и другие. Просто используйте это на каждом дочернем элементе, который вы хотите синхронизировать с родительской ViewGroup:
android:duplicateParentState="true"
Обратите внимание, что он дублирует все состояние, а не только включенное состояние. Это может быть то, что вы хотите! Конечно, этот подход лучше всего подходит, если вы загружаете макет XML.
Ответ 8
private void disableLL(ViewGroup layout){
for (int i = 0; i < layout.getChildCount(); i++) {
View child = layout.getChildAt(i);
child.setClickable(false);
if (child instanceof ViewGroup)
disableLL((ViewGroup) child);
}
}
и вызовите метод следующим образом:
RelativeLayout rl_root = (RelativeLayout) findViewById(R.id.rl_root);
disableLL(rl_root);
Ответ 9
подробности
- Студия Android 3.1.4
- Котлин 1.2.70
- проверено в minSdkVersion 19
Решение
fun View.forEachChildView(closure: (View) -> Unit) {
closure(this)
val groupView = this as? ViewGroup ?: return
val size = groupView.childCount - 1
for (i in 0..size) {
groupView.getChildAt(i).forEachChildView(closure)
}
}
использование
val layout = LinearLayout(context!!)
layout.forEachChildView { it.isEnabled = false }
val view = View(context!!)
view.forEachChildView { it.isEnabled = false }
val fragment = Fragment.instantiate(context, "fragment_id")
fragment.view?.forEachChildView { it.isEnabled = false }
Ответ 10
Используйте ниже рекурсивную функцию, чтобы сделать ваши дочерние представления видимыми или удален.
Первый аргумент - это ваше родительское представление, а второй аргумент решает, хотите ли вы видеть дочерние родительские представления или исчезнуть. true = visible false = go
private void layoutElemanlarininGorunumunuDegistir(View view, boolean gorunur_mu_olsun) {
ViewGroup view_group;
try {
view_group = (ViewGroup) view;
Sabitler.konsolaYazdir(TAG, "View ViewGroup imiş!" + view.getId());
} catch (ClassCastException e) {
Sabitler.konsolaYazdir(TAG, "View ViewGroup değilmiş!" + view.getId());
return;
}
int view_eleman_sayisi = view_group.getChildCount();
for (int i = 0; i < view_eleman_sayisi; i++) {
View view_group_eleman = view_group.getChildAt(i);
if (gorunur_mu_olsun) {
view_group_eleman.setVisibility(View.VISIBLE);
} else {
view_group_eleman.setVisibility(View.GONE);
}
layoutElemanlarininGorunumunuDegistir(view_group_eleman, gorunur_mu_olsun);
}
}
Ответ 11
Хотя это не совсем то же самое, что отключать представления в макете, стоит упомянуть, что вы можете запретить детям всех получать штрихи (без необходимости повторять иерархию макета), переопределяя метод ViewGroup # onInterceptTouchEvent (MotionEvent):
public class InterceptTouchEventFrameLayout extends FrameLayout {
private boolean interceptTouchEvents;
// ...
public void setInterceptTouchEvents(boolean interceptTouchEvents) {
this.interceptTouchEvents = interceptTouchEvents;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return interceptTouchEvents || super.onInterceptTouchEvent(ev);
}
}
Затем вы можете запретить детям получать события касания:
InterceptTouchEventFrameLayout layout = (InterceptTouchEventFrameLayout) findViewById(R.id.layout);
layout.setInterceptTouchEvents(true);
Если у вас есть прослушиватель кликов, установленный на layout
, он все равно будет запущен.
Ответ 12
Если вы хотите отключить набор или сказать определенный вид вида. Предположим, вы хотите отключить фиксированное количество кнопок с определенным текстом или без текста, тогда вы можете использовать массив этого типа и пропустить через элементы массива при отключении кнопок с помощью свойства setEnabled (false) Вы можете сделать это при вызове функции следующим образом:
public void disable(){
for(int i=0;i<9;i++){
if(bt[i].getText().equals("")){//Button Text condition
bt[i].setEnabled(false);
}
}
}
Ответ 13
Я улучшил ответ tütü, чтобы правильно отключить компоненты EditText и RadioButton. Кроме того, я разделяю способ, которым я нашел, чтобы изменить видимость вида и добавить прозрачность в отключенные представления.
private static void disableEnableControls(ViewGroup view, boolean enable){
for (int i = 0; i < view.getChildCount(); i++) {
View child = view.getChildAt(i);
child.setEnabled(enable);
if (child instanceof ViewGroup){
disableEnableControls((ViewGroup)child, enable);
}
else if (child instanceof EditText) {
EditText editText = (EditText) child;
editText.setEnabled(enable);
editText.setFocusable(enable);
editText.setFocusableInTouchMode(enable);
}
else if (child instanceof RadioButton) {
RadioButton radioButton = (RadioButton) child;
radioButton.setEnabled(enable);
radioButton.setFocusable(enable);
radioButton.setFocusableInTouchMode(enable);
}
}
}
public static void setLayoutEnabled(ViewGroup view, boolean enable) {
disableEnableControls(view, enable);
view.setEnabled(enable);
view.setAlpha(enable? 1f: 0.3f);
}
public static void setLayoutEnabled(ViewGroup view, boolean enable, boolean visibility) {
disableEnableControls(view, enable);
view.setEnabled(enable);
view.setAlpha(enable? 1f: 0.3f);
view.setVisibility(visibility? View.VISIBLE: View.GONE);
}
Ответ 14
Это довольно отложенный ответ. Но это может помочь кому-то. Многие ответы, упомянутые выше, кажутся хорошими. Но если ваш layout.xml имеет вложенные группы представлений. Тогда выше ответы могут не дать полный результат. Поэтому я опубликовал свое мнение как фрагмент. С помощью приведенного ниже кода можно отключить все представления (включая вложенные группы представлений).
ПРИМЕЧАНИЕ. Старайтесь избегать вложенных ViewGroups, поскольку они не рекомендуются.
private void setEnableView(boolean b) {
LinearLayout layout = (LinearLayout)findViewById(R.id.parent_container);
ArrayList<ViewGroup> arrVg = new ArrayList<>();
for (int i = 0; i < layout.getChildCount(); i++) {
View child = layout.getChildAt(i);
if (child instanceof ViewGroup) {
ViewGroup vg = (ViewGroup) child;
arrVg.add(vg);
}
child.setEnabled(b);
}
for (int j=0;j< arrVg.size();j++){
ViewGroup vg = arrVg.get(j);
for (int k = 0; k < vg.getChildCount(); k++) {
vg.getChildAt(k).setEnabled(b);
}
}
}
Ответ 15
Я знаю это поздно, но в последнее время схожая проблема, я исправил это с помощью этого подхода - не нужно изменять ваш текущий макет или что-нибудь, что вы можете легко обрабатывать все динамически, используя две строки кода. ниже мой ответ
fooobar.com/questions/353691/...
Ответ 16
В Kotlin вы можете использовать isDuplicateParentStateEnabled = true
прежде чем View
будет добавлено в ViewGroup
.
Как setDuplicateParentStateEnabled
методе setDuplicateParentStateEnabled
, если у дочернего представления есть дополнительные состояния (например, состояние флажка для флажка), родительский вид не будет влиять на них.
Аналогом xml является android:duplicateParentState="true"
.
Ответ 17
Я лично использую что-то вроде этого (вертикальный обход дерева с помощью рекурсии)
fun ViewGroup.deepForEach(function: View.() -> Unit) {
this.forEach { child ->
child.function()
if (child is ViewGroup) {
child.deepForEach(function)
}
}
}
использование:
viewGroup.deepForEach { isEnabled = false }
Ответ 18
Для меня RelativeLayout или любой другой макет в конце XML файла с шириной и высотой, установленной в match_parent, с атрибутом focusable и clickable, установленным в true.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
Ответ 19
чтобы отключить представление, вы должны вызвать метод setEnabled с аргументом false для аргумента.
например:
Button btn = ...
btn.setEnabled(false);
Ответ 20
Установите
android:descendantFocusability="blocksDescendants"
для просмотра ViewGroup. Все потомки не будут фокусироваться.