您的位置:首页 > 其它

事件分发机制的原理总结

2015-12-06 11:47 302 查看
触摸事件相关方法:

ViewGroup

•dispatchTouchEvent(MotionEvent) 用于分发touch事件

•onInterceptTouchEvent(MotionEvent) 用于是否中断touch事件,true中断,false不中断,默认false

•onTouchEvent(MotionEvent) 用于处理touch事件,true消费事件,false不消费,默认false

View、Activity

•dispatchTouchEvent(MotionEvent) 用于分发touch事件

•onTouchEvent(MotionEvent) 用于处理touch事件

金典的默认事件分发流程图:



总结:

1.touch事件的传递其实就是一连续的方法调用.由activity的dispatchTouchEvent方法开始调用

2.消费了Down事件的view称为目标View,目标View可以接收后续的事件,非目标View不可以接收后续事件

3.Down事件如果没有任何View消费,则后续事件不再传递,直接由Activity的onTouchEvent方法处理,所以,想要处理其他事件首先要消费Down事件,即返回true

4.拦截:

1)如果Down事件拦截,则把当前事件交给自己的onTouchEvent方法处理,如果此方法不消费Down事件,则事件丢失,后续的事件交由Activity的onTouchEvent方法处理

2)如果Down事件不拦截且其他事件拦截,则Down事件不处理,且会传一个Cancel事件给目标View,后续的事件就会交给自己的onTouchEvent方法处理,此时拦截该事件的view就变成了目标view,虽然没有消费Down事件

3)如果Down事件不拦截,在事件分发返回后,如果Down事件没有被消费,那么会把事件交给自己的onTouchEvnet方法处理.

4)如果不拦截事件,且能接收到事件,则说明有目标View的存在,在事件分发方法返回后,是不会把事件交给自己的onTouchEvent方法处理,因为自己不是目标View,即使目标View在处理Move,Up事件时返回了false.

5.Activity不管有无目标View,也不管是Down还是Move,Up事件,只要分发方法返回后,如果事件没有被消费,则交给自己的onTouchEvent方法处理

6.可以调用getParent().requestDisallowInterceptTouchEvent(true)方法来请求父View禁止拦截事件,这个方法会递归的请求所有的父View禁止拦截事件.

注意:如果想要获取一个整体的touch事件,一定要消费Down事件,如果Down事件的时候只是请求父View禁止拦截不消费Down事件,虽然父View不再拦截了,但后续的事件也是接收不到的,哪个父View消费了Down事件,哪个父View就可以接收到后续事件.

7.如果2个View并没有包含关系,而是重叠关系,则处于上面的View先拿到事件,如果消费了,则事件不会传递给另一个View

8.容器一般都是调用ViewGroup的dispatchTouchEvent方法进行事件分发,其他类一般是调用View类的dispatchEvent方法进行事件分发;通常默认的onInterceptTouchEvent,onTouchEvent方法都是返回false.

9.所有的事件分发都是调用super.dispatchTouchEvent(ev)完成的,所以如果不调用这句代码则事件中止传递。但是要中止事件传递一般不会这么做,一般是在onInterceptTouchEvent(MotionEvent) 方法中处理,如果该方法返回true则中止。既然dispatchTouchEvent(ev)方法可以中止事件传递,为什么还要设计一个onInterceptTouchEvent(MotionEvent) 方法呢? 因为子View可以请求父View不要拦截事件,如ListView是可以上下滑动的,当处于滑动状态时候就会请求禁止父View的拦截触摸事件方法,让ListView可以一直获取到touch事件进行滚动。假设这个时候父View又想响应触摸事件怎么办?可以写到dispatchTouchEvent方法中,因为事件是先传到这个方法,然后再传递给ListView的。

10.如果父View的onInterceptTouchEvent方法返回true,则事件会直接传递到父View的onTouchEvent方法处理,此时如果onTouchEvent方法返回false的话,则事件会继续向下分发,即会继续调用子View的dispatchTouchEvent方法;否则不会继续分发,而是向上返回到调用处.

11.应用技巧:

1)父类的onTouchEvent方法要想执行,要么是等所有的子View都不消费Down事件,要么是父View把事件拦截.

2)如果子View消费了Down事件,而父View又不想拦截,却又想处理这个事件,则父View可以通过onInterceptTouchE方法或者dispatchTouchEvent方法来处理Touch事件

3)如果子View请求了禁止父View拦截事件,但父View又还想拦截的话,可以在父View的dispatchTouchEvent方法中不调用super.dispatcheTouchEvent方法则把事件拦截了.

4)如果在Activity中一定要响应一些触摸事件,又怕事件传递后被消费了,可以直接在Activity的dispatchTouchEvent方法中处理即可.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: