今天在做项目的时候,遇到了一个问题,就是需要把一个常按监听事件,加到一个linearlayout中,但是,这个linearlayout中有其他的button、textview等控件,这样就导致当我们常按textview的时候,触发的是textview等子控件的常按事件。今天我们讨论的并不是如何解决这个问题,而是在解决这个问题的过程中,我遇到的android:clickable 跟 android:longClickable 这两个xml属性。
先看这两个属性在xml中的用法
<Button android:id="@+id/bt0" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ff0000" android:clickable="false" android:longClickable="false" android:text="long fasle" />
这两个属性有什么意义呢,我们看Button 中对这两个属性的处理
case com.android.internal.R.styleable.View_clickable: clickable = a.getBoolean(attr, clickable); break; case com.android.internal.R.styleable.View_longClickable: longClickable = a.getBoolean(attr, longClickable); break; } } a.recycle(); setFocusable(focusable); setClickable(clickable); setLongClickable(longClickable);
我们很明白,它其实就是setClick 跟 setLongClick方法xml中的使用。
那么问题就来了。在代码里设置了上面两个属性为false,但当我在代码中给这这个按钮设置点击事件的时候,这两个点击事件仍然可以触发,而且似乎没有影响。后来我发现了问题所在。我们看一下
setOnClickListener 方法中到底做了什么事情
public void setOnClickListener(OnClickListener l) { if (!isClickable()) { setClickable(true); } getListenerInfo().mOnClickListener = l; } public void setOnLongClickListener(OnLongClickListener l) { if (!isLongClickable()) { setLongClickable(true); } getListenerInfo().mOnLongClickListener = l; }
我们很清除就知道了,之所以这两个属性设置没有效果,是因为,当我们给一个控件添加点击事件的时候,它们会重新把这个控件的clickable 属性进行设置。所以,如果我们想要禁掉一个控件的点击事件,我们必须是在点击事件以后使用
setLongClickable(false); setClickable(false)
方法