Android 如何暂时取消LinearLayout中包含的按钮收听单击?

Android 如何暂时取消LinearLayout中包含的按钮收听单击?,android,android-studio,Android,Android Studio,我有一堆按钮,根据应用程序的状态,监听事件是没有意义的。LinearLayout上是否存在阻止其子按钮侦听事件的属性/方法或其他方法?当然,我可以去我寻找一种方法来分离每个按钮的事件,但我当然想去做的简单和最方便的方法。我还可以禁用所有按钮。我了解到,当我试图为禁用的按钮显示tost时,禁用的按钮不会以艰难的方式侦听事件。备选方案1 更新答案! 我已经在视图类上使用kotlin扩展函数测试了如下将所有单击侦听器设置为所有视图层次结构 private fun View.dissableClick(

我有一堆按钮,根据应用程序的状态,监听事件是没有意义的。LinearLayout上是否存在阻止其子按钮侦听事件的属性/方法或其他方法?当然,我可以去我寻找一种方法来分离每个按钮的事件,但我当然想去做的简单和最方便的方法。我还可以禁用所有按钮。我了解到,当我试图为禁用的按钮显示tost时,禁用的按钮不会以艰难的方式侦听事件。

备选方案1

更新答案! 我已经在视图类上使用kotlin扩展函数测试了如下将所有单击侦听器设置为所有视图层次结构

private fun View.dissableClick() {
        setOnClickListener(null)
        if (this is ViewGroup) {
            for (v in children) {
                v.setOnClickListener(null)
            }
        }
}
因此您可以调用root.dissableClick

您还可以尝试使用isEnabled=false和v.isEnabled=false代替setOnClickListenernull

备选方案2信用@Amin Mousavi答案

也可从本文档中获取。在自定义线性布局的情况下,需要创建自定义视图组

class InterceptLinearLayout @JvmOverloads constructor(
    context: Context, attr: AttributeSet? = null, defStyleAttr: Int = 0
) : LinearLayout(context, attr, defStyleAttr) {

    var intercept = false

    override fun onInterceptTouchEvent(ev: MotionEvent?) = when (intercept) {
        true -> true
        else -> super.onInterceptTouchEvent(ev)
    }
}
root.intercept = true
注意:如果您不为所有超级构造函数提供重载,您的应用程序将崩溃

从备选方案1更改xml

更新答案! 我已经在视图类上使用kotlin扩展函数测试了如下将所有单击侦听器设置为所有视图层次结构

private fun View.dissableClick() {
        setOnClickListener(null)
        if (this is ViewGroup) {
            for (v in children) {
                v.setOnClickListener(null)
            }
        }
}
因此您可以调用root.dissableClick

您还可以尝试使用isEnabled=false和v.isEnabled=false代替setOnClickListenernull

备选方案2信用@Amin Mousavi答案

也可从本文档中获取。在自定义线性布局的情况下,需要创建自定义视图组

class InterceptLinearLayout @JvmOverloads constructor(
    context: Context, attr: AttributeSet? = null, defStyleAttr: Int = 0
) : LinearLayout(context, attr, defStyleAttr) {

    var intercept = false

    override fun onInterceptTouchEvent(ev: MotionEvent?) = when (intercept) {
        true -> true
        else -> super.onInterceptTouchEvent(ev)
    }
}
root.intercept = true
注意:如果您不为所有超级构造函数提供重载,您的应用程序将崩溃


从更改xml有一种方法可以扩展LinearLayout并重写其方法,如果要从其子级窃取触摸事件,则返回true;如果要其子级接收触摸事件,则返回false。像这样的

class CustomLinearLayout extends LinearLayout {
    //...

    private preventTouchOnChildren = false;

    public void setPreventTouchOnChildren(boolean value) {
        preventTouchOnChildren = value;
    }

    public boolean onInterceptTouchEvent (MotionEvent ev) {
        if (preventTouchOnChildren) 
            return true;
        else
            return false;
    }

    //...
}

有一种方法可以扩展LinearLayout并重写其方法,如果要从其子级窃取触摸事件,则返回true;如果要其子级接收触摸事件,则返回false。像这样的

class CustomLinearLayout extends LinearLayout {
    //...

    private preventTouchOnChildren = false;

    public void setPreventTouchOnChildren(boolean value) {
        preventTouchOnChildren = value;
    }

    public boolean onInterceptTouchEvent (MotionEvent ev) {
        if (preventTouchOnChildren) 
            return true;
        else
            return false;
    }

    //...
}

LinearLayout有一个名为setEnabled的属性,我已经尝试过并。。。猜猜看。。。没用!你不应该这样做,听起来不错,但最好的方法是:mybutton.sentEnabled=false其他选项是绘制一个对话框视图,以避免在操作完成之前在屏幕上进行交互。我认为android的体系结构不适合处理这种复杂性。复杂的事件冒泡将浪费资源。这只是一个猜测,我对Android Engenering一无所知。你想得太多了。只是不要那样做。始终使用本机解决方案。其他解决方案只是权宜之计。读得好:LinearLayout有一个名为setEnabled的属性,我已经尝试过并且。。。猜猜看。。。没用!你不应该这样做,听起来不错,但最好的方法是:mybutton.sentEnabled=false其他选项是绘制一个对话框视图,以避免在操作完成之前在屏幕上进行交互。我认为android的体系结构不适合处理这种复杂性。复杂的事件冒泡将浪费资源。这只是一个猜测,我对Android Engenering一无所知。你想得太多了。只是不要那样做。始终使用本机解决方案。其他解决方案只是权宜之计。可读性好:clickable属性不影响孩子们是否对click事件做出反应。换句话说,这对使用kotlin/java不起作用?我使用的是kotlin。我只是在Java中尝试过,但它也不起作用。无论如何,更改布局上的clickable属性不会截获子级的click事件。但是,我仍然有一个小评论。不要在尝试1中删除子项的OnClickListener,而是将其clickable属性设置为False。因为这里设置的是子对象的可点击属性,而不是父对象;因此,它将生效。我注意到你还说可以使用isEnabled,这也很好:当然可以这样做@nizarth可点击属性不会影响孩子们是否对点击事件做出反应。换句话说,这对使用kotlin/java不起作用?我使用的是kotlin。我只是在Java中尝试过,但它也不起作用。无论如何,更改布局上的clickable属性不会截获子级的click事件。但是,我仍然有一个小评论。不要在尝试1中删除子项的OnClickListener,而是将其clickable属性设置为False。因为这里设置的是子对象的可点击属性,而不是父对象;因此,它将生效。我注意到你还说可以使用isEnabled,这也很好:当然可以@Nizar这样做