Android事件传递

总则

  • 事件触发的第一个回调方法为: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为父类方法返回值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值