我们先从分发的对象以及作用的方法讲起

典型的事件有以下三种:ACTION_DOWN:手指刚接触屏幕的瞬间、ACTION_MOVE:手指在屏幕上滑动、ACTION_UP:手指刚离开屏幕的瞬间。

事件分发的三个对象:activity、viewgroup、view。

作用的三个方法:dispatchTouchEvent()、onInterceptTouchEvent()、onTouchEvent()。

具体的方法如图所示:

android 分发事件 安卓的事件分发_android 分发事件


事件分发机制的流程如下图所示

android 分发事件 安卓的事件分发_android 分发事件_02

dispatchTouchEvent()

作用于activity、viewgroup、view身上。

true:代表消费该事件,并不向下传递。

false: 传到父类的onTouchEvent(),不消费该事件,由于activity没有父类所以直接结束。

super:向下传递给onInterceptTouchEvent,如果作用在Activity上,由于Activity没有onInterceptTouchEvent方法所以直接传递给子类的dispatchTouchEvent方法;如果作用在View上,则直接传递给自己的onTouchEvent方法去处理。

onInterceptTouchEvent()

作用于viewgroup身上

true:代表拦截该事件,并传递给自己的onTouchEvent()处理。

false/super:代表不拦截该事件,传递给子view的dispatchTouchEvent()方法处理。

在使用拦截方法onInterceptTouchEvent的时候,需要注意两种特殊情况。

1.一次事件中,该方法一旦被调用返回了true就不会在调用了。假设在Down事件被调用时返回了true,那么Move与Up事件便不会再去调用这个方法,而是直接去执行onTouchEvent方法。

2.假设ViewGroup没有拦截Down事件,而是拦截了Move事件,那么这个Down会直接传递给子类View,而后面的Move由于被拦截了,但是他并不会传递给自身的onTouchEvent方法,而是被作为一个Cancel方法传递给子类的View,而后面再来的Move则会被传递给自身的View去处理,而子类的View也不再会收到后续事件。

onTouchEvent()

作用于activity、viewgroup、view身上

true:代表消费该事件。

super/false:代表不处理或者说没有能力处理这个事件。则传递给父类的onTouchEvent去处理。

我们平时在使用click事件作为点击的时候,其实click事件是包含在onTouch事件里面的。在onTouch事件里面其实包含了onTouchEvent、performClick以及Click事件,而我们一般使用的click事件其实优先级别是最低了,只有当前面的事件返回false不处理才会轮到click去触发处理,如果前面有一个返回了true那么事件都会被消费掉,不会传递给click去处理。

接下来我们来谈谈常见的三种事件分发

ACTION_DOWN事件:

1 .在dispatchTouchEvent()中返回true时,只拦截当前ACTION_DOWN的事件传递,dispatchTouchEvent的返回值不论是true还是fasle并不影响后续MOVE与UP的事件操作,后续的ACTION_MOVE和ACTION_UP事件仍然会经过dispatchTouchEvent方法,然后继续按事件的传递顺序走下去。

2 .在onTouchEvent()中返回true时,后续的ACTION_MOVE和ACTION_UP也会被拦截。

3 .在onInterceptTouchEvent()中返回true时,后续的ACTION_MOVE和ACTION_UP也会被拦截,但后续的MOVE、UP方法就不会在执行这个方法了,而是直接去执行自身的onTouch方法。onInterceptTouchEvent一旦被拦截,一次事件只执行一次,后续MOVE与UP不再执行onInterceptTouchEvent()方法。