总则
- 事件触发的第一个回调方法为:dispatchTouchEvent(MotionEvent)
- 事件最终会在onTouchEvent方法中消费。
- 哪个控件消费了ACTION_DOWN事件,接下来的所有事件都会在该控件的onTouchEvent方法中消费。
总体流程(Activity, ViewGroup, View)
视图层级为:Activity contentView中有个ViewGroup,ViewGroup中有个View。点击到View中,事件传递过程如下:
首先找到谁消费的ACTION_DOWN事件,ACTION_DOWN事件传递
- Activity接收到event,经过Activity.dispatchTouchEvent(event)方法向下分发给ViewGroup
- ViewGroup接收到event,经过ViewGroup.dispatchTouchEvent(event)方法根据ViewGroup.onInterceptTouchEvent(event)方法判断是否向下分发event,如果分发则向下分发给View
- View接收到event,经过View.dispatchTouchEvent(event)方法将event分发给View.onTouchEvent(event)
- View.onTouchEvent是否消费ACTION_DOWN事件,如果不消费,事件回传给ViewGroup.dispatchTouchEvent(event)
- ViewGroup.dispatchTouchEvent(event)将事件分发给ViewGroup.onTouchEvent(event)
- ViewGroup.onTouchEvent(event)是否消费event事件,如果不消费,事件回传给Activity.dispatchTouchEvent(event)
- 至此,如果ACTION_DOWN没有被消费,则执行Activity.onTouchEvent(event)
事件跟踪
以Activity、FrameLayout、TextView为例,事件传递监听(DOWN、MOVE、UP)如下:
Activity, FrameLayout, TextView全为默认设置时的监听
activity.dispatchTouchEvent: 1, action = ACTION_DOWN
frameLayout.dispatchTouchEvent: 1, action = ACTION_DOWN
frameLayout.onInterceptTouchEvent: 1, action = ACTION_DOWN
frameLayout.onInterceptTouchEvent: 2, action = ACTION_DOWN result = false
textView.dispatchTouchEvent: 1, action = ACTION_DOWN
textView.onTouchEvent: 1, action = ACTION_DOWN
textView.onTouchEvent: 2, action = ACTION_DOWN result = false
textView.dispatchTouchEvent: 2, action = ACTION_DOWN result = false
frameLayout.onTouchEvent: 1, action = ACTION_DOWN
frameLayout.onTouchEvent: 2, action = ACTION_DOWN result = false
frameLayout.dispatchTouchEvent: 2, action = ACTION_DOWN result = false
activity.onTouchEvent: 1, action = ACTION_DOWN
activity.onTouchEvent: 2, action = ACTION_DOWN result = false
activity.dispatchTouchEvent: 2, action = ACTION_DOWN result = false
// 以上为 ACTION_DOWN 事件
activity.dispatchTouchEvent: 1, action = ACTION_MOVE
activity.onTouchEvent: 1, action = ACTION_MOVE
activity.onTouchEvent: 2, action = ACTION_MOVE result = false
activity.dispatchTouchEvent: 2, action = ACTION_MOVE result = false
// 以上为 ACTION_MOVE 事件
activity.dispatchTouchEvent: 1, action = ACTION_UP
activity.onTouchEvent: 1, action = ACTION_UP
activity.onTouchEvent: 2, action = ACTION_UP result = false
activity.dispatchTouchEvent: 2, action = ACTION_UP result = false
// 以上为 ACTION_UP 事件
当TextView.onTouchEvent(event)返回值设置为true, 其它为默认值时
activity.dispatchTouchEvent: 1, action = ACTION_DOWN
frameLayout.dispatchTouchEvent: 1, action = ACTION_DOWN
frameLayout.onInterceptTouchEvent: 1, action = ACTION_DOWN
frameLayout.onInterceptTouchEvent: 2, action = ACTION_DOWN result = false
textView.dispatchTouchEvent: 1, action = ACTION_DOWN
textView.onTouchEvent: 1, action = ACTION_DOWN
textView.onTouchEvent: 2, action = ACTION_DOWN result = false
textView.dispatchTouchEvent: 2, action = ACTION_DOWN result = true
frameLayout.dispatchTouchEvent: 2, action = ACTION_DOWN result = true
activity.dispatchTouchEvent: 2, action = ACTION_DOWN result = true
// 以上为 ACTION_DOWN 事件
activity.dispatchTouchEvent: 1, action = ACTION_MOVE
frameLayout.dispatchTouchEvent: 1, action = ACTION_MOVE
frameLayout.onInterceptTouchEvent: 1, action = ACTION_MOVE
frameLayout.onInterceptTouchEvent: 2, action = ACTION_MOVE result = false
textView.dispatchTouchEvent: 1, action = ACTION_MOVE
textView.onTouchEvent: 1, action = ACTION_MOVE
textView.onTouchEvent: 2, action = ACTION_MOVE result = false
textView.dispatchTouchEvent: 2, action = ACTION_MOVE result = true
frameLayout.dispatchTouchEvent: 2, action = ACTION_MOVE result = true
activity.dispatchTouchEvent: 2, action = ACTION_MOVE result = true
// 以上为 ACTION_MOVE 事件
activity.dispatchTouchEvent: 1, action = ACTION_UP
frameLayout.dispatchTouchEvent: 1, action = ACTION_UP
frameLayout.onInterceptTouchEvent: 1, action = ACTION_UP
frameLayout.onInterceptTouchEvent: 2, action = ACTION_UP result = false
textView.dispatchTouchEvent: 1, action = ACTION_UP
textView.onTouchEvent: 1, action = ACTION_UP
textView.onTouchEvent: 2, action = ACTION_UP result = false
textView.dispatchTouchEvent: 2, action = ACTION_UP result = true
frameLayout.dispatchTouchEvent: 2, action = ACTION_UP result = true
activity.dispatchTouchEvent: 2, action = ACTION_UP result = true
// 以上为 ACTION_UP 事件
当FrameLayout.onTouchEvent(event)返回值设置为true, 其它为默认值时
activity.dispatchTouchEvent: 1, action = ACTION_DOWN
frameLayout.dispatchTouchEvent: 1, action = ACTION_DOWN
frameLayout.onInterceptTouchEvent: 1, action = ACTION_DOWN
frameLayout.onInterceptTouchEvent: 2, action = ACTION_DOWN result = false
textView.dispatchTouchEvent: 1, action = ACTION_DOWN
textView.onTouchEvent: 1, action = ACTION_DOWN
textView.onTouchEvent: 2, action = ACTION_DOWN result = false
textView.dispatchTouchEvent: 2, action = ACTION_DOWN result = false
frameLayout.onTouchEvent: 1, action = ACTION_DOWN
frameLayout.onTouchEvent: 2, action = ACTION_DOWN result = false
frameLayout.dispatchTouchEvent: 2, action = ACTION_DOWN result = true
activity.dispatchTouchEvent: 2, action = ACTION_DOWN result = true
// 以上为 ACTION_DOWN 事件
activity.dispatchTouchEvent: 1, action = ACTION_MOVE
frameLayout.dispatchTouchEvent: 1, action = ACTION_MOVE
frameLayout.onTouchEvent: 1, action = ACTION_MOVE
frameLayout.onTouchEvent: 2, action = ACTION_MOVE result = false
frameLayout.dispatchTouchEvent: 2, action = ACTION_MOVE result = true
activity.dispatchTouchEvent: 2, action = ACTION_MOVE result = true
// 以上为 ACTION_MOVE 事件
activity.dispatchTouchEvent: 1, action = ACTION_UP
frameLayout.dispatchTouchEvent: 1, action = ACTION_UP
frameLayout.onTouchEvent: 1, action = ACTION_UP
frameLayout.onTouchEvent: 2, action = ACTION_UP result = false
frameLayout.dispatchTouchEvent: 2, action = ACTION_UP result = true
activity.dispatchTouchEvent: 2, action = ACTION_UP result = true
// 以上为 ACTION_UP 事件
当TextView.onTouchEvent(event)与FrameLayout.onTouchEvent(event)返回值都为true时(与只设置TextView.onTouchEvent(event)返回值为true时一样):
activity.dispatchTouchEvent: 1, action = ACTION_DOWN
frameLayout.dispatchTouchEvent: 1, action = ACTION_DOWN
frameLayout.onInterceptTouchEvent: 1, action = ACTION_DOWN
frameLayout.onInterceptTouchEvent: 2, action = ACTION_DOWN result = false
textView.dispatchTouchEvent: 1, action = ACTION_DOWN
textView.onTouchEvent: 1, action = ACTION_DOWN
textView.onTouchEvent: 2, action = ACTION_DOWN result = false
textView.dispatchTouchEvent: 2, action = ACTION_DOWN result = true
frameLayout.dispatchTouchEvent: 2, action = ACTION_DOWN result = true
activity.dispatchTouchEvent: 2, action = ACTION_DOWN result = true
// 以上为 ACTION_DOWN 事件
activity.dispatchTouchEvent: 1, action = ACTION_MOVE
frameLayout.dispatchTouchEvent: 1, action = ACTION_MOVE
frameLayout.onInterceptTouchEvent: 1, action = ACTION_MOVE
frameLayout.onInterceptTouchEvent: 2, action = ACTION_MOVE result = false
textView.dispatchTouchEvent: 1, action = ACTION_MOVE
textView.onTouchEvent: 1, action = ACTION_MOVE
textView.onTouchEvent: 2, action = ACTION_MOVE result = false
textView.dispatchTouchEvent: 2, action = ACTION_MOVE result = true
frameLayout.dispatchTouchEvent: 2, action = ACTION_MOVE result = true
activity.dispatchTouchEvent: 2, action = ACTION_MOVE result = true
// 以上为 ACTION_MOVE 事件
activity.dispatchTouchEvent: 1, action = ACTION_UP
frameLayout.dispatchTouchEvent: 1, action = ACTION_UP
frameLayout.onInterceptTouchEvent: 1, action = ACTION_UP
frameLayout.onInterceptTouchEvent: 2, action = ACTION_UP result = false
textView.dispatchTouchEvent: 1, action = ACTION_UP
textView.onTouchEvent: 1, action = ACTION_UP
textView.onTouchEvent: 2, action = ACTION_UP result = false
textView.dispatchTouchEvent: 2, action = ACTION_UP result = true
frameLayout.dispatchTouchEvent: 2, action = ACTION_UP result = true
activity.dispatchTouchEvent: 2, action = ACTION_UP result = true
// 以上为 ACTION_UP 事件
FrameLayout.onInterceptTouchEvent(event)返回值都为true,其它为默认时:
activity.dispatchTouchEvent: 1, action = ACTION_DOWN
frameLayout.dispatchTouchEvent: 1, action = ACTION_DOWN
frameLayout.onInterceptTouchEvent: 1, action = ACTION_DOWN
frameLayout.onInterceptTouchEvent: 2, action = ACTION_DOWN result = false
frameLayout.onTouchEvent: 1, action = ACTION_DOWN
frameLayout.onTouchEvent: 2, action = ACTION_DOWN result = false
frameLayout.dispatchTouchEvent: 2, action = ACTION_DOWN result = false
activity.onTouchEvent: 1, action = ACTION_DOWN
activity.onTouchEvent: 2, action = ACTION_DOWN result = false
activity.dispatchTouchEvent: 2, action = ACTION_DOWN result = false
// 以上为 ACTION_DOWN 事件
activity.dispatchTouchEvent: 1, action = ACTION_MOVE
activity.onTouchEvent: 1, action = ACTION_MOVE
activity.onTouchEvent: 2, action = ACTION_MOVE result = false
activity.dispatchTouchEvent: 2, action = ACTION_MOVE result = false
// 以上为 ACTION_MOVE 事件
activity.dispatchTouchEvent: 1, action = ACTION_UP
activity.onTouchEvent: 1, action = ACTION_UP
activity.onTouchEvent: 2, action = ACTION_UP result = false
activity.dispatchTouchEvent: 2, action = ACTION_UP result = false
// 以上为 ACTION_UP 事件
参数说明: 1为进入方法时执行,2为离开方法时执行,action为MotionEvent.ACTION_, result为父类方法返回值