Android 关于setOnclickListener 对事件分发的影响

来源:互联网 发布:开根号的算法 编辑:程序博客网 时间:2024/06/01 07:55

1.以前一直觉得事件分发都是那么回事,感觉自己掌握了,可是最近发现自己远远没有掌握。自己还是太水了。经过一番思考参考别人的文章,解决了我遇到的困惑。这里着重推荐这位大牛的博客。http://blog.csdn.net/yanbober/article/details/45887547/感谢他无私的奉献,写了那么多字的文章。


2、在一个布局中,添加一个Button,然后再mainactivity 中对这个布局增加监听,点击button看看,布局的监听事件是否会执行?结果不会。但是假如把button换成view或者textview,在试试,结果会触发。这是不是很奇怪,真的很奇怪,因此对这个问题,我展开了深入探究。在学习过程中发现上面哪位大神的文章,不仅仅解决了我这个问题,而且也学到了很多知识。在这里我就做一个笔记,直接引用他文章里面的结论。


3.onclick事件,究竟会在哪一步被调用?

结论:当button被点击了,会执行onTouch方法,一般默认的onTouch方法返回false。表示不处理,反之true表示处理了。

在接受到点击动作的时候,程序的执行顺序:  dispatchTouchEvent------->onTouch----->onTouchEvent.。onclick方法是在onTouchEvent方法中调用的,具体位置是在onTouchEvent的up操作之后调用的。

当onTouch 返回true的时候,也就是说onTouch处理了这个动作,事件不会分发下去。因此不会执行onTouchEvent事件,因此也不会执行onclick方法。所以你设置的view.setOnclikListener没得什么用。


4.回到2中的那个问题中来,结合原代码我们看下setOnClickListener方法:

 public void setOnClickListener(@Nullable OnClickListener l) {        //增加监听后就将这个控件设置成了setclickable了        if (!isClickable()) {            setClickable(true);        }        getListenerInfo().mOnClickListener = l;    }

结合源码可以发现:这个方法中不管那个被点击的view是不是clickable状态,setonclickListener之后,它都会变成clickable状态。这个clickable很有意思。

view.setonclickListener()那么这个view的onTouchEvent方法的返回值就是true。反之假如一个TextView事先不是clickable状态的,在不加setonclicklistener监听之前,它的onTouchEvent为返回值为false。这个结论我做过实验。在这里不贴代码。


有些组件默认状态就是clickable:例如button,有些组件默认状态不是clickable,例如TextView,这样就可以解释2的问题了。

当点击button的时候,事件分发机制,会把这个事件交给button的onTouchEvent来处理,因为button是clickable的,因此在button中返回true,表示处理了这个事件,因此点击button。布局的onclick事件不会进行,因为事件还没传递到布局的onTouchEvent中。

当把button换成Textview的时候,当事件传递到textview的onTouchEvent的时候,因为textView是不clickable状态所以,返回false,导致事件传递给了布局的onTouchEvent。前面说 了 任何view只要设置了onclicklistener就会变成clickable状态,进而它的onTouchEvent会反会true,表示对这个动作做处理,因此会执行onclick事件。

因此 只要在button标签中设置一个clickable=false 那么 你点击button,布局文件也会执行onclick事件。


还有一个场景也是因为这个导致的。就是listview的item ,里面有button,你设置listview.setOnitemListener ,点击item的时候会没得反应,原因和这里也有点类似。

当然这些都是我的理解,肯定有不对的地方。有问题请留言,大家交流下






0 0
原创粉丝点击