我们先从分发的对象以及作用的方法讲起
典型的事件有以下三种:ACTION_DOWN:手指刚接触屏幕的瞬间、ACTION_MOVE:手指在屏幕上滑动、ACTION_UP:手指刚离开屏幕的瞬间。
事件分发的三个对象:activity、viewgroup、view。
作用的三个方法:dispatchTouchEvent()、onInterceptTouchEvent()、onTouchEvent()。
具体的方法如图所示:
事件分发机制的流程如下图所示
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()方法。