Android事件分发一共涉及三个事件dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent。其中onInterceptTouchEvent事件只有ViewGroup才具有。这三个事件恰好对应着三种返回值true、false、super.xxx()。
下面通过一张图来了解事件分发的流程(图1)。
事件分发过程中,会出现两种状态,第一种是没有被拦截,第二种被拦截。下面具体情况具体分析。
ACTION_DOWN是所有事件的第一步。所以我们先针对ACTION_DOWN来进行分析。
ACTION_DOWN:
1.事件没有被拦截:
在图1中黑色的路线就是完整的没有拦截的事件分发流程。每个方法都是调用super.xxx()把事件向下进行分发。当达到View层事件仍然没有处理,就会把事件回溯到上一个控件的onTouchEvent()事件,如果仍然不被处理,就一直返回直到返回到最顶层。
2.事件被拦截:
(1)自己拦截了(消费了)
return true就是代表此方法要拦截事件,图中红色的路径。事件被拦截后,就会停止分发,往后的事件也不会再向下分发。
onInterceptTouchEvent()返回true表示此事件,“我(ViewGroup)”要进行拦截,默认是不拦截。拦截之后把事件交给自己的onTouchEvent()。
(2)拦截了,但是没有消费
return false事件不再向下传递,转而回溯到父类的onTounchEvent()。
dispatchTouchEvent()和onTouchEvent()返回true就是把事件传递到上层空间的onTounchEvent()。
ACTION_DOWN/ACTION_UP:
dispatchTouchEvent在进行事件分发的时候,只有前一个事件(如ACTION_DOWN)返回true,才会收到ACTION_MOVE和ACTION_UP的事件。
例如:
1.在Activity的onTounchEvent()拦截事件。ACTION_MOVE/UP会直接传递到Activity的onTouchEvent()上。
2.在view的onTouchEvent拦截事件,ACTION_MOVE/UP会直接传递到View的onTouchEvent上。
还有可以在其他的地方进行ACTION_DOWN的拦截,就是return true。就不一个个绘图了,原理都是一样的
其他:
1.拦截父类事件:getParent().requestDisallowInterceptTouchEvent(true)。让父类不处理事件,把事件传递给子类。
测试项目地址:https://github.com/lvdouzhou/androidEventDispatch