Android的事件分发机制
更多面试题请看这里:https://interview.raoyunsoft.com/
面试题专栏会持续更新欢迎关注订阅
事件分发起点
- 事件起点是
DecorView(Activity的根视图) - 完整触摸事件包含:
ACTION_DOWN(1个) →ACTION_MOVE(0或多个) →ACTION_UP(1个)
ViewGroup和View的关系
ViewGroup::dispatchTouchEvent核心流程
-
拦截判断
boolean intercepted = onInterceptTouchEvent(ev); // 默认返回false- 重写时可自定义拦截逻辑(如滑动冲突处理)
- 返回true表示拦截事件
-
遍历子View(未拦截时)
ArrayList<View> preorderedList = buildTouchDispatchChildList(); // 按Z轴排序 for (int i = childrenCount - 1; i >= 0; i--) {View child = getAndVerifyPreorderedView(i, children);if (!isTransformedTouchPointInView(x, y, child, null)) continue; // 跳过触点外Viewif (dispatchTransformedTouchEvent(ev, child)) { // 子View消费事件newTouchTarget = addTouchTarget(child); // 记录消费Viewbreak; // 终止遍历} } -
事件分发逻辑
ACTION_DOWN:- 优先由子View处理
- 所有子View未处理时触发
super.dispatchTouchEvent()(即View父类逻辑)
ACTION_MOVE/UP:while (mFirstTouchTarget != null) {dispatchTransformedTouchEvent(ev, target.child); // 直接传递给记录的View }
核心分发规则
-
事件传递流程
Activity → DecorView → ViewGroup → ... → TargetView -
关键拦截点
onInterceptTouchEvent作用:- 拦截
ACTION_DOWN向子View传递 - 中断后续
ACTION_MOVE/UP传递,转由ViewGroup自身处理
- 拦截
-
消费判定
- 子View通过
onTouchEvent()返回true表示消费事件 - 所有子View未消费时:
- ViewGroup触发
super.dispatchTouchEvent() - 最终调用Activity的
onTouchEvent()
- ViewGroup触发
- 子View通过
-
多级传递示例
重要特性
-
责任链模式
- 事件从顶层ViewGroup向子View递归传递
- 任一环节消费即终止传递
-
触摸目标锁定
ACTION_DOWN确定消费View后,后续事件直接路由到该View- 通过
mFirstTouchTarget链表维护消费关系
-
Z轴排序机制
float z = elevation + translationZ; // 决定View的触摸优先级
💡 实战技巧:解决滑动冲突时,常通过重写
onInterceptTouchEvent在ACTION_MOVE中动态拦截事件,结合requestDisallowInterceptTouchEvent实现父子控件协调处理。
