Disabling all child views inside the layout
Asked Answered
L

4

17

I saw many threads related to this, before posting my question. But none worked for me. I have a RelativeLayout with many other layouts and fragments as children. I want to disable all the children of "content_view" as well as the content_view itself on a button click. I tried

contentView.setDisabled(false);

This didn't work. I've also tried

for (int i = 0; i < layout.getChildCount(); i++) {
    View child = layout.getChildAt(i);
    child.setEnabled(false);
}

Even this didn't work. What am I doing wrong? Please find my .xml code below. I even tried placing a view above all views. Even that didn't solve my problem.

<RelativeLayout
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:id="@+id/content_view"
    android:background="#ffffff">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_below="@+id/channel_actionbar"
        android:layout_marginLeft="0dp"
        android:layout_marginTop="0dp"
        android:duplicateParentState="true">

        <FrameLayout
            android:layout_height="match_parent"
            android:layout_width="match_parent"
            android:id="@+id/body_container"
            android:layout_below="@+id/channel_actionbar"
            android:duplicateParentState="true">

            <RelativeLayout
                android:layout_height="match_parent"
                android:layout_width="match_parent"
                android:id="@+id/channelList"
                android:duplicateParentState="true">

                <com.mobile.subview.ScrollViewWithScrollListener
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:id="@+id/scrollView"
                    android:layout_alignParentTop="false"
                    android:duplicateParentState="true">

                    <RelativeLayout
                        android:orientation="vertical"
                        android:layout_width="fill_parent"
                        android:layout_height="fill_parent"
                        android:duplicateParentState="true">

                        <FrameLayout
                            android:layout_width="fill_parent"
                            android:layout_height="fill_parent"
                            android:id="@+id/imagePlaceHolder"
                            android:duplicateParentState="true"></FrameLayout>

                        <TableLayout
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:id="@+id/channelTable"
                            android:layout_below="@+id/imagePlaceHolder"
                            android:duplicateParentState="true"></TableLayout>

                        <com.mobile.subview.CustomTextView
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:text="You do not qualify for any engagements or channels.  Please check back later."
                            app:typeface="fonts/HelveticaNeue"
                            app:customStyle="Regular"
                            android:id="@+id/noChannelsMessage"
                            android:textColor="#000"
                            android:textSize="@dimen/contentTextSize"
                            android:visibility="gone"
                            android:duplicateParentState="true"/>
                    </RelativeLayout>
                </com.mobile.subview.ScrollViewWithScrollListener>

                <com.mobile.subview.ParallaxImage
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:id="@+id/header"
                    android:adjustViewBounds="true"
                    android:layout_alignParentTop="true"
                    android:scaleType="fitStart"
                    android:visibility="invisible"
                    android:duplicateParentState="true"/>
            </RelativeLayout>

            <RelativeLayout
                android:layout_height="match_parent"
                android:layout_width="match_parent"
                android:layout_below="@+id/channel_actionbar"
                android:id="@+id/sibling_view"
                android:visibility="gone"
                android:duplicateParentState="true"></RelativeLayout>

        </FrameLayout>
    </LinearLayout>

    <RelativeLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:visibility="invisible"
        android:id="@+id/retailersContainer"
        android:layout_marginLeft="0dp"
        android:duplicateParentState="true"
        android:layout_below="@+id/channel_actionbar">

        <fragment
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:name="com.mobile.subview.List"
            android:id="@+id/retailers"
            android:duplicateParentState="true"/>

        <FrameLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_below="@+id/retailers"
            android:id="@+id/retailerClickBlocker"
            android:duplicateParentState="true"></FrameLayout>
    </RelativeLayout>

    <RelativeLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="@dimen/actionBarHeight"
        android:layout_alignParentTop="true"
        android:id="@+id/channel_actionbar"
        android:background="#F8F8F8"
        android:layout_marginLeft="0dp"
        android:duplicateParentState="true">

        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/shared_navmenu_button"
            android:id="@+id/show_menu_button"
            android:layout_centerVertical="true"
            android:background="@null"
            android:scaleType="fitCenter"
            android:layout_marginLeft='5px'
            android:duplicateParentState="true"/>

        <com.mobile.subview.CustomTextView
            android:id="@+id/channel_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:textSize="@dimen/titleTextSize"
            android:textColor="#000"
            android:text="Test Title"
            app:typeface="fonts/HelveticaNeue"
            app:customStyle="Medium"
            android:visibility="gone"
            android:duplicateParentState="true"/>


        <ImageView
            android:id="@+id/logo"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/shared_navbar_logo2x"
            android:visibility="gone"
            android:scaleType="fitCenter"
            android:duplicateParentState="true"/>

        <com.mobile.subview.CustomButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:id="@+id/channel_done_btn"
            app:typeface="fonts/HelveticaNeue"
            app:customStyle="Regular"
            android:visibility="gone"
            android:duplicateParentState="true"/>

        <com.mobile.subview.CustomButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            app:typeface="fonts/HelveticaNeue"
            app:customStyle="Regular"
            android:id="@+id/channel_share_btn"
            android:visibility="gone" />

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="1dp"
            android:background="#D6D6D6"
            android:id="@+id/divider"
            android:layout_alignParentBottom="true"
            android:duplicateParentState="true"/>

    </RelativeLayout>

    <View
        android:visibility="gone"
        android:id="@+id/click_preventing_view"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#66000000"
        android:clickable="false" />

</RelativeLayout>
Lucid answered 5/11, 2013 at 22:34 Comment(0)
D
33

Because your layouts are so heavily nested, you need to recursively disable the views. Instead of using your method, try something like this:

private static void disable(ViewGroup layout) {
    layout.setEnabled(false);
    for (int i = 0; i < layout.getChildCount(); i++) {
        View child = layout.getChildAt(i);
        if (child instanceof ViewGroup) {
            disable((ViewGroup) child);
        } else {
            child.setEnabled(false);
        }
    }
}

then call:

disable(content_view);
Detonation answered 5/11, 2013 at 22:39 Comment(7)
Im getting exception here... thread exiting with uncaught exception (group=0x4108b2a0) 11-05 17:46:09.354 19082-19082/air.com.test.mobile W/System.err﹕ java.lang.StackOverflowError 11-05 17:46:09.378 19082-19082/air.com.test.mobile W/System.err﹕ at android.view.View.setEnabled(View.java:5673)Lucid
Why isn't android:duplicateParentState="true" not working while changing the parent's state?Lucid
It might work if you make all of your views have duplicateParentState, but it would have to go all the way down the hierarchy. I'm also not totally sure if duplicateParentState applies to the disabled state; it looks like it only applies to the visual styling of the elements, not their behavior.Detonation
This works as expected. But it is disabling other layouts outside content_viewLucid
No problem! If this worked, don't forget to accept the answer by hitting the green checkbox. Thanks!Detonation
This is causing a different problem. So I can't accept the answer. However I can up vote it. Thanks for the help!Lucid
Sorry I did a mistake. Its working fine now!! Accepting your answerLucid
C
4

Even though the answer is expected instead of using recursion I think the below code will do the trick.This is what I used to disbale it. I just passed parentlayout and whether to show or hide as a boolean parameter

private void disable(LinearLayout layout, boolean enable) {
        for (int i = 0; i < layout.getChildCount(); i++) {
            View child = layout.getChildAt(i);
            child.setEnabled(enable);
            if (child instanceof ViewGroup) {
                ViewGroup group = (ViewGroup) child;
                for (int j = 0; j < group.getChildCount(); j++) {
                    group.getChildAt(j).setEnabled(enable);
                }
            }

        }
Calculous answered 4/12, 2014 at 12:41 Comment(0)
B
0

Here are Kotlin versions:

Using Android KTX

fun View.changeEnableChildren(enable: Boolean) {
    isEnabled = enable
    (this as? ViewGroup)?.let {
        forEach {
            changeEnableChildren(enable)
        }
    }
}

Without Android KTX

fun View.changeEnableChildren(enable: Boolean) {
    isEnabled = enable
    (this as? ViewGroup)?.let {
        for (i in 0..it.childCount) {
            changeEnableChildren(enable)
        }           
    }
}

Note: recursive method may cause StackOverFlowError in that case you should replace changeEnableChildren(enable) with isEnabled=enable

Bissell answered 4/2, 2020 at 8:27 Comment(0)
F
0

apply android:duplicateParentState="true" to the children

Fregoso answered 4/11, 2020 at 11:20 Comment(1)
This is a good solution, but some widgets ignore it, for example spinner for disable.Tribunal

© 2022 - 2024 — McMap. All rights reserved.