Как отключить все виды внутри макета? - программирование
Подтвердить что ты не робот

Как отключить все виды внутри макета?

Например, у меня есть:

<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?

4b9b3361

Ответ 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. Все потомки не будут фокусироваться.