Android布局使所有孩子都无法点击

22 android

我正在使用 Relative LayoutTextViews等中的许多按钮.clickable除非发生某些事件,否则我希望所有这些按钮都没有.

我尝试过设置,RelativeLayout.setClickable(false);但布局中的所有元素都是clickable.

我知道这样做的一种方法是设置每个子元素clickable但不是一个合适的方式,因为我在布局中有很多子元素,如按钮文本视图等,我不能让每个子元素都不可点击.

在这里我的问题是如何将所有设置setClickable(false);layout

Kas*_*rdi 25

当你说点击时,你实际上是指触摸吗?触摸事件是逐个元素完成的.他们首先被发送到顶级,如果它处理它,如果它没有处理它,它会进入视图的每个孩子.

当创建触摸事件时,onTouch调用链中的视图方法,如果其中任何一个返回true(真正的意思是"我处理了这个!")它将停止向孩子们发送.

要使您的relativelayout块触及所有子项的触摸和点击,您只需设置onTouchListener,如下所示:

YOUR_RELATIVE_LAYOUT.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // ignore all touch events
        return true;
    }
});
Run Code Online (Sandbox Code Playgroud)

这将忽略相对布局(及其所有子项)上发生的所有触摸事件,其中包括简单的触摸然后释放事件(称为点击).


Dav*_*ung 17

我找到了另一种方法来实现这一目标.你可以在RelativeLayout中的所有兄弟视图的顶部创建一个阻塞的LinearLayout,如下所示:

<RelativeLayout
    android:id="@+id/rl_parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- the children views begins -->
    ...
    <!-- the children views ends -->

    <LinearLayout
        android:id="@+id/ll_mask"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/transparent"
        android:clickable="true"
        android:orientation="horizontal"
        android:visibility="visible"/>

</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

稍后您可以将LinearLayout的可见性切换为GONE,以允许再次单击子视图:

mMask.setVisibility(View.VISIBLE); // blocks children
mMask.setVisibility(View.GONE); // children clickable
Run Code Online (Sandbox Code Playgroud)

  • 不完全是我倾向于使用的,但在一天结束时它节省了很多时间。谢谢,+1。 (4认同)
  • 好答案。有太多子级的布局没有性能问题。 (3认同)

vip*_*tal 11

您可以使用以下功能查找所有子视图并取消单击.

  public void setClickable(View view) {
    if (view != null) {
        view.setClickable(false);
        if (view instanceof ViewGroup) {
            ViewGroup vg = ((ViewGroup) view);
            for (int i = 0; i < vg.getChildCount(); i++) {
                setClickable(vg.getChildAt(i));
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Oz *_*bat 7

一个简单的Kotlin 扩展解决方案,用于禁用/启用视图及其所有子视图:

fun View.isUserInteractionEnabled(enabled: Boolean) {
    isEnabled = enabled
    if (this is ViewGroup && this.childCount > 0) {
        this.children.forEach {
            it.isUserInteractionEnabled(enabled)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并用以下方式调用它:

view.isUserInteractionEnabled(false)
Run Code Online (Sandbox Code Playgroud)

  • 这是 Kotlin 代码的扩展函数 (2认同)

ved*_*ant 5

一个非常简单且完全证明的方法是创建一个子类并覆盖onInterceptTouchEvent

public class MyRelativeLayout extends RelativeLayout {
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // true if you do not want the children to be clickable.
        return mShouldInterceptAllTouch;
    }
}
Run Code Online (Sandbox Code Playgroud)

无需调用任何孩子的方法。

您仍然可以调用setOnClickListener您的myRelativeLayout对象。此外,您可以在 XML 中使用该类,就像使用RelativeLayout