Как я могу отключить все виды внутри макета? - PullRequest
63 голосов
/ 15 августа 2011

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

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

Ответы [ 18 ]

110 голосов
/ 15 ноября 2011

это рекурсивно для 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);
       }
    }
}
85 голосов
/ 15 августа 2011

Другой способ - вызвать 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);
}
70 голосов
/ 14 февраля 2015

Ответ Туту на правильном пути, но его рекурсия немного неловкая. Я думаю, что это чище:

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);
        }
    }
}
16 голосов
/ 06 октября 2017

На самом деле, что работа для меня:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

и отменить это:

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
10 голосов
/ 12 декабря 2012

Давайте изменим код 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" />

и во время выполнения сделайте его видимым.Примечание: родительский макет вашего группового обзора должен быть либо относительным, либо макетом фрейма.Надеюсь, это поможет.

8 голосов
/ 27 ноября 2018

Если вы заинтересованы в отключении представлений в определенной ViewGroup, вы можете использовать интересное, возможно, немного неясное duplicateParentState. Состояние просмотра - это набор логических атрибутов, таких как нажатие, включение, активация и другие. Просто используйте это для каждого дочернего элемента, которого вы хотите синхронизировать с родительской ViewGroup:

android:duplicateParentState="true"

Обратите внимание, что он дублирует все состояние, а не только включенное состояние. Это может быть то, что вы хотите! Конечно, этот подход лучше всего подходит для загрузки макета XML.

8 голосов
/ 14 января 2016

Если какой-то отчаянный разработчик прокручивает здесь, у меня есть другая возможность сделать это. Что также отключает прокрутку, насколько я экспериментировал с ней. Идея состоит в том, чтобы использовать такой элемент 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 будет перехватывать событие клика и не передавать его базовым элементам.

2 голосов
/ 17 сентября 2018

Подробнее

  • Студия 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  }
2 голосов
/ 10 ноября 2017
  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);
1 голос
/ 02 февраля 2017

Хотя это не совсем то же самое, что отключение представлений в макете, стоит отметить, что вы можете запретить всем дочерним элементам получать прикосновения (без необходимости повторения иерархии макета) с помощьюпереопределение метода 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, он все равно будет срабатывать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...