Android的触摸事件传递分析
Android的触摸事件总是传递到Activity的根视图DecorView,DecorView再进行分发。
在一组连续的触摸事件中, MotionEvent.ACTION_DOWN
代表TouchEvent的开始,传递进DecorView.dispatchTouchEvent
,并且后续的所有MotionEvent都将传递进DecorView.dispatchTouchEvent
来分发。DecorView.dispatchTouchEvent
实际上调用父类ViewGroup的dispatchTouchEvent方法。
知识点一、ViewGroup对MotionEvent.ACTION_DOWN事件的处理可如下描述:
ViewGroup.dispatchTouchEvent
将调用onInterceptTouchEvent
试图拦截MotionEvent.ACTION_DOWN
,拦截成功的话进入步骤3,否则进入步骤2;ViewGroup.dispatchTouchEvent
根据MotionEvent.ACTION_DOWN
的位置遍历子控件view children,并把MotionEvent.ACTION_DOWN
传递给childView的View.dispatchTouchEvent
。如果有childView的View.dispatchTouchEvent
返回true那这个childView就被记为TouchTarget,ViewGroup.dispatchTouchEvent
也返回true。如果没有找到TouchTarget,则进入步骤3;ViewGroup.dispatchTouchEvent
把MotionEvent.ACTION_DOWN
传递给父类View的View.dispatchTouchEvent
,并返回View.dispatchTouchEvent
的返回值。
知识点二、DecorView对MotionEvent.ACTION_DOWN事件的处理:
DecorView对MotionEvent.ACTION_DOWN的处理过程基本就是上述3个步骤,实际的处理结果如下:
- 由于DecorView是根视图只负责触摸事件分发,上述步骤1总是失败而步骤3总是返回false。
- 如果步骤2没有找到TouchTarget,那后续的MotionEvent.ACTION_MOVE、MotionEvent.ACTION_UP、MotionEvent.ACTION_CANCEL只会传递到
DecorView.dispatchTouchEvent
并且不会再分发。 - 如果步骤2找到TouchTarget,那后续的MotionEvent都会传递到这个TouchTarget。
三、MotionEvent.ACTION_DOWN事件在DecorView内View和ViewGroup的传递过程分析:
基于以上两点,MotionEvent.ACTION_DOWN事件实际上是在DecorView内的View和ViewGroup传递,我们把知识点一步骤2遍历view children过程中的子控件记为PotentialTarget,那么知识点一步骤2可以分解成:
- 如果PotentialTarget是ViewGroup的子类,那么PotentialTarget的
dispatchTouchEvent
将重复知识点一的3个步骤,否则进入步骤2; - PotentialTarget的
dispatchTouchEvent
返回onTouchEvent
的返回值;
四、MotionEvent.ACTION_DOWN之后的触摸事件在DecorView内View和ViewGroup的传递过程分析:
(To be done)