Android事件分发机制

来源:互联网 发布:怎么联系淘宝店铺客服 编辑:程序博客网 时间:2024/06/06 15:43

借鉴自郭霖博文http://blog.csdn.net/guolin_blog/article/details/9153747,这里浓缩一下


首先,onTouch和onClick的对比


onTouch是优先于onClick的。

意思是同样注册了这两个监听,onTouch会先被调用


其次,onTouch的返回值

一个触摸屏幕的手势传下来,如果你设置为true,那么就代表这个手势就被你留在这里了,你可以一直使用它。

如果你返回false,那么手势就会继续传递,直到找到返回true的地方,同时你返回了false,你在onTouch中定义的操作也将失去作用。


明白分发机制

一个触摸事件,都是不断调用每一个view的dispatchTouchEvent(分发方法),不断地分发下去。


从dispatchTouchEvent源码中得知

满足分发需要3个条件

1.必须注册OnTouchListener的监听

2.控件是enable的

(控件enable和控件clickable的区别:enable=false,控件不可点击;setclickable=false必须在注册click之后声明才有效,

因为注册监听这个过程,源码中会先判断你是否clickable,如果是false,那就会设置为true)

3.mOnTouchListener.onTouch(this, event)如果我们onTouch中返回true,则条件全成立了,那样手势就被留在这里了。

如果onTouch中返回false,那么条件条件有一个不成立,就会继续执行子view的dispatchTouchEvent(如果当前是viewgroup)。


为什么onTouch返回了false后onClick也跟着失效了

因为onTouch中会调用到performClick(),在这个方法里面回调onclick


onTouch和onTouchEvent的区别

onTouch优先于onTouchEvent执行。



下面是viewgroup(可以存放view的容器,自身也是view,如linearlayout)的事件分发流程


如果你点击到一个button,你不会首先调用button的dispatchTouchEvent方法,而是会调用包裹着这个button的布局的dispatchTouchEvent方法,即viewgroup或者说是linerlayout类型的布局。


执行viewgroup的dispatchTouchEvent的过程中,会判断onTouchInterrupt的返回值,如果是true,则会拦截子view的事件,如果是false则不会拦截子view的事件。反而会先行执行子view的onTouch(子view一般onTouch返回true来消费这个事件,如果你不想消费,会传给viewgroup也行)


盗个图