Android的事件分发机制 - 实践

更多面试题请看这里:https://interview.raoyunsoft.com/
面试题专栏会持续更新欢迎关注订阅

事件分发起点
  • 事件起点是DecorView(Activity的根视图)
  • 完整触摸事件包含:
    ACTION_DOWN(1个) → ACTION_MOVE(0或多个) → ACTION_UP(1个)
ViewGroup和View的关系
继承
包含
包含
包含
包含
包含
View
ViewGroup
onInterceptTouchEvent
dispatchTouchEvent
onTouchEvent
ViewGroup::dispatchTouchEvent核心流程
  1. 拦截判断

    boolean intercepted = onInterceptTouchEvent(ev); // 默认返回false
    • 重写时可自定义拦截逻辑(如滑动冲突处理)
    • 返回true表示拦截事件
  2. 遍历子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; // 跳过触点外View
      if (dispatchTransformedTouchEvent(ev, child)) { // 子View消费事件
      newTouchTarget = addTouchTarget(child); // 记录消费View
      break; // 终止遍历
      }
      }
  3. 事件分发逻辑

    • ACTION_DOWN
      • 优先由子View处理
      • 所有子View未处理时触发super.dispatchTouchEvent()(即View父类逻辑)
    • ACTION_MOVE/UP
      while (mFirstTouchTarget != null) {
      dispatchTransformedTouchEvent(ev, target.child); // 直接传递给记录的View
      }
核心分发规则
  1. 事件传递流程

    Activity → DecorView → ViewGroup → ... → TargetView
  2. 关键拦截点

    • onInterceptTouchEvent作用:
      • 拦截ACTION_DOWN向子View传递
      • 中断后续ACTION_MOVE/UP传递,转由ViewGroup自身处理
  3. 消费判定

    • 子View通过onTouchEvent()返回true表示消费事件
    • 所有子View未消费时:
      • ViewGroup触发super.dispatchTouchEvent()
      • 最终调用Activity的onTouchEvent()
  4. 多级传递示例

    ViewGroup0 ViewGroup1 TextView ACTION_DOWN ACTION_DOWN "返回true(消费)" 返回true "ACTION_MOVE/UP" "ACTION_MOVE/UP" ViewGroup0 ViewGroup1 TextView
重要特性
  1. 责任链模式

    • 事件从顶层ViewGroup向子View递归传递
    • 任一环节消费即终止传递
  2. 触摸目标锁定

    • ACTION_DOWN确定消费View后,后续事件直接路由到该View
    • 通过mFirstTouchTarget链表维护消费关系
  3. Z轴排序机制

    float z = elevation + translationZ; // 决定View的触摸优先级

实战技巧:解决滑动冲突时,常通过重写onInterceptTouchEventACTION_MOVE中动态拦截事件,结合requestDisallowInterceptTouchEvent实现父子控件协调处理。

posted @ 2026-01-24 13:54  gccbuaa  阅读(1)  评论(0)    收藏  举报