前言:
刚开始接触事件分发的时候, 很多人都是这样的
1. 先看网上的流程图
2. 看源码
结果:流程图看懂了, 但是源码好像关联不起来, 分析起来很难.
我个人总结的原因:
- 网上常见的流程图, 很多都是只画了一种事件(ACTION_DOWN)
- 所谓的事件都是一组出现的, 并不是单个.
- ViewGroup的dispatchTouchEvent源码,是几个事件都合并一切写的, 所以分析可能起来比较费劲.
一. 事件分发 解决了什么问题?
布局嵌套或重叠时, 我们的触摸屏幕,这个事件到底给谁去执行
二. 事件的分类
需知:事件都是一组出现的, 而不是单个的.
事件分类:
- 手指触碰到屏幕 (ACTION_DOWN)
- 手指在屏幕停留或滑动 (ACTION_MOVE)
- 手指离开屏幕 (ACTION_UP)
- 结束这组事件 (ACTION_CANCEL) 非人为触碰
常见的事件组:
- ACTION_DOWN(开始) ---》ACTION_MOVE---》...... ---》ACTION_UP(人为结束)
- ACTION_DOWN(开始) ---》ACTION_MOVE---》...... ---》ACTION_CANCEL(非人为结束)
三. 事件分发的流程
View事件分发机制.png1. ACTION_DOWN 事件的分发, 如上图:
①:方法全部返回false,会按照黄色箭头走完, 也即是网上说的“U”型路径
②:如果onInterceptTouchEvent() 返回true, 则会直接去执行自己的onTouchEvent(), 后面继续按黄色箭头走
③:如果onTouchEvent()返回true, 则不会继续按黄色箭头走
2. ACTION_MOVE 事件的分发, 如上图:
影响因素:和ACTION_DOWN事件 在 某个View中onTouchEvent() 中返回值有关
①:返回false, 分发流程 和 ACTION_DOWN事件是一样的.
②:返回true, 则ACTION_MOVE 会走最短路线找到对应的View, 执行onTouchEvent(),也就是网上说的“L”型路线
3. ACTION_UP 和 ACTION_CANCEL事件的分发, 如上图:
和ACTION_MOVE 的 分发流程是一样的,
区别:这是一组事件结束的标记
四. 事件分发 这样设计有什么好处呢?
- 从事件处理的角度--onTouchEvent(): 是从手机最上层的控件, 一层一层往下去处理, 很符合人类的直觉.
- 事件分发的角度--dispatchTouchEvent():,父亲需要先拿到优先权, 然后才能派发给底下的孩子,不想给我就自己享受, 这个也很符合人类的直觉.
-
特殊情况: 我的子View 一定要拿到事件,怎么办呢?
系统提供了一个方法:getParent().requestDisallowInterceptTouchEvent(true)
网友评论