How to disable all views inside the layout?

For example, I have:

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

Is there a way to disable (setEnable (false)) all elements inside LinearLayout my_layout ?

+67
android android-layout
Aug 15 '11 at 18:19
source share
20 answers

Another way is to call setEnabled () for each child (for example, if you want to do additional checking on the child before disconnecting)

 LinearLayout layout = (LinearLayout) findViewById(R.id.my_layout); for (int i = 0; i < layout.getChildCount(); i++) { View child = layout.getChildAt(i); child.setEnabled(false); } 
+88
Aug 15 '11 at 19:00
source share
— -

this recursive for 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); } } } 
+113
Nov 14 2018-11-11T00:
source share

The answer to tutu is on the right track, but its recursion is a bit uncomfortable. I think this is cleaner:

 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); } } } 
+70
Feb 13 '15 at 21:55
source share

In fact, what a job for me:

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

and cancel it:

 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); 
+17
Oct. 06 '17 at 10:35 on
source share

Change tütü code

 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); } } } 

I think it makes no sense to just turn off group display. If you want to do this, there is another way that I used for the same purpose. Create a sibling view of your group view:

 <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" /> 

and at runtime make it visible. Note. The parent layout of the group view must be either relative or layout. Hope this helps.

+11
Dec 12 '12 at 5:57
source share

If some desperate developer scrolls here, I have another option to do this. Which also disables scrolling as far as I experimented with it. The idea is to use a View element like this in a RelativeLayout, under all of your user interface elements.

 <View android:id="@+id/shade" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/primaryShadow" android:visibility="gone"/> 

Therefore, it must be “gone” before some condition. And then you set its visibility to VISIBLE when you want to disable your interface. You must also implement OnClickListener for this view. This OnClickListener will capture the click event and will not pass it to the underlying elements.

+8
Jan 14 '16 at 13:50
source share

If you are interested in disabling views in a specific ViewGroup, then you can use the interesting, perhaps a little obscure duplicateParentState . A view state is a set of logical attributes, such as clicking, turning on, activating, and others. Just use this on every child you want to sync with the parent ViewGroup:

 android:duplicateParentState="true" 

Note that it duplicates the entire state, not just the enabled state. It could be what you want! Of course, this approach is best if you are loading an XML layout.

+8
Nov 27 '18 at 7:53
source share
  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); } } 

and call the method as follows:

 RelativeLayout rl_root = (RelativeLayout) findViewById(R.id.rl_root); disableLL(rl_root); 
+2
Nov 10 '17 at 7:36
source share

the details

  • Android Studio 3.1.4
  • Kotlin 1.2.70
  • tested in minSdkVersion 19

Decision

 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) } } 

using

 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
Sep 16 '18 at 22:39
source share

Use the recursive function below to make your child views visible or deleted . The first argument is your parent view, and the second argument decides whether you want to see the child parent views or disappear. 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); } } 
+1
Oct 11 '16 at 12:34
source share

Although this is not quite the same as turning off views in the layout, it's worth mentioning that you can prevent children from getting strokes (without having to repeat the layout hierarchy) by overriding the ViewGroup # onInterceptTouchEvent (MotionEvent) method :

 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); } } 

Then you can prevent children from receiving touch events:

 InterceptTouchEventFrameLayout layout = (InterceptTouchEventFrameLayout) findViewById(R.id.layout); layout.setInterceptTouchEvents(true); 

If you have a click listener installed on layout , it will still run.

+1
02 Feb '17 at 0:26
source share

If you want to disable the set or say a certain kind of view. Suppose you want to disable a fixed number of buttons with or without certain text, then you can use an array of this type and pass through the array elements when you disable the buttons using the setEnabled (false) property. You can do this when calling the function as follows:

 public void disable(){ for(int i=0;i<9;i++){ if(bt[i].getText().equals("")){//Button Text condition bt[i].setEnabled(false); } } } 
0
Feb 22 '18 at 9:28
source share

I improved tütü 's answer to properly disable the EditText and RadioButton components. In addition, I share the way I found to change view visibility and add transparency to disabled views.

 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); } 
0
Mar 19 '18 at 13:42
source share

This is a pretty delayed answer. But it can help someone. Many of the answers mentioned above seem to be good. But if your layout.xml has nested view groups. Then the above answers may not give the full result. Therefore, I published my opinion as a fragment. Using the code below, you can disable all views (including nested view groups).

NOTE. Try to avoid nested ViewGroups as they are not recommended.

  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); } } } 
0
Mar 22 '18 at 5:45
source share

I know this late, but a similar problem lately, I fixed it with this approach - no need to change your current layout or anything that you can easily handle everything dynamically using two lines of code. below is my answer

stack overflow

0
May 09 '19 at 11:51
source share

In Kotlin, you can use isDuplicateParentStateEnabled = true before the View is added to the ViewGroup .

Like the setDuplicateParentStateEnabled method of the setDuplicateParentStateEnabled method, if the child view has additional states (for example, the state of the checkbox for the checkbox), the parent view will not affect them.

The analogue of xml is android:duplicateParentState="true" .

0
Jun 11 '19 at 10:08 on
source share

I personally use something like this (vertical tree traversal using recursion)

 fun ViewGroup.deepForEach(function: View.() -> Unit) { this.forEach { child -> child.function() if (child is ViewGroup) { child.deepForEach(function) } } } 

using:

  viewGroup.deepForEach { isEnabled = false } 
0
Jun 17 '19 at 20:42
source share

For me, RelativeLayout or any other layout at the end of an XML file with the width and height set to match_parent, with the focusable and clickable attribute set to 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> 
0
Sep 18 '19 at 17:32
source share

to disable the view, you must call the setEnabled method with the false argument for the argument. eg:

 Button btn = ... btn.setEnabled(false); 
-one
Mar 16 '15 at 13:05
source share

Set

 android:descendantFocusability="blocksDescendants" 

to view the ViewGroup. All descendants will not focus.

-one
Apr 29 '15 at 11:08
source share



All Articles