禁用布局内的所有子视图

17

在发布我的问题之前,我看到了很多与此相关的线程。但是没有一个适用于我。我有一个RelativeLayout,其中包含许多其他布局和片段作为其子项。当单击一个按钮时,我想禁用“content_view”的所有子项以及content_view本身。我尝试过

contentView.setDisabled(false);

这个不起作用。我还尝试过

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

即使这样也没有起作用。我做错了什么?请在下面找到我的 .xml 代码。 我甚至尝试将一个视图放在所有视图上方。但那也无法解决我的问题。

<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>
4个回答

32

因为你的布局被嵌套得很深,所以需要对视图进行递归禁用。不要使用你的方法,尝试使用以下代码:

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

然后调用:

disable(content_view);

我在这里遇到了异常...线程退出时未捕获的异常(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:在android.view.View.setEnabled(View.java:5673)处。 - LoveMeSomeFood
1
为什么在更改父级状态时android:duplicateParentState="true"无法正常工作? - LoveMeSomeFood
如果您让所有视图都具有duplicateParentState,那么它可能会起作用,但必须一直延伸到整个层次结构。我也不完全确定duplicateParentState是否适用于禁用状态;看起来它只适用于元素的视觉样式,而不是它们的行为。 - Haldean Brown
这个按预期工作。但它会禁用 content_view 之外的其他布局。 - LoveMeSomeFood
抱歉,我犯了一个错误。现在它已经正常工作了!接受你的答案。 - LoveMeSomeFood
显示剩余3条评论

3

虽然预期的答案不是使用递归,但我认为以下代码可以解决问题。这是我用来禁用它的方法。我只是将parentlayout和是否显示或隐藏作为布尔参数传递。

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

        }

0

android:duplicateParentState="true"应用于子元素


这是一个不错的解决方案,但有些小部件会忽略它,比如禁用旋转器。 - Style-7

0

以下是 Kotlin 版本:

使用 Android KTX

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

没有 Android KTX

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

注意:递归方法可能会导致StackOverFlowError,在这种情况下,您应该将changeEnableChildren(enable)替换为isEnabled=enable


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接