本文同步发表于 微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

一、事件处理流程

1. 事件产生 → 2. 收集响应链并分发 → 3. 触发回调

二、核心概念:事件响应链

1. 响应链构建规则

  • 右子树优先的后序遍历

  • 例子:组件树结构

组件1 (根)
├── 组件2 (左子)
│   └── 组件4
└── 组件3 (右子)
    └── 组件5
  • 点击组件5时响应链:5 → 3 → 1

2. hitTestBehavior 影响规则

  • Default:命中时阻塞兄弟节点,不阻塞子节点

  • None:自身不接收事件,不阻塞任何节点

  • Block:命中时阻塞兄弟节点和父节点

  • Transparent:自身测试,不阻塞任何节点

  • BLOCK_HIERARCHY (API 20+):自身和子节点测试,阻塞低优先级兄弟和父节点

  • BLOCK_DESCENDANTS (API 20+):自身和后代都不测试,不影响祖先

三、命中测试(触摸测试)

1. 测试原理

  • 用户首次按下时确定响应范围

  • 自上而下、自右向左遍历组件树

  • 收集命中的手势和事件

  • 逐级向上冒泡整合

2. 命中条件

  1. 组件在组件树中

  2. 事件坐标在响应热区内

  3. 组件非透明

四、干预命中的三种方式

1. 触摸热区设置(responseRegion)

Button("按钮")
    .responseRegion([
        { x: 0, y: 0, width: '30%', height: '100%' },     // 左侧1/3
        { x: '70%', y: 0, width: '30%', height: '100%' }  // 右侧1/3
    ])
    // 中间40%区域不响应

坐标规则

  • x/y:可正可负百分比(100%右/下,-100%左/上)

  • width/height:只能正百分比

  • 百分比基于组件自身宽高计算

2. 触摸测试控制(hitTestBehavior)

  • 静态配置,声明时确定行为

  • 影响兄弟/父子节点的收集

3. 自定义事件拦截(onTouchIntercept)

.onTouchIntercept((event) => {
    // 动态返回 HitTestMode
    return HitTestMode.Block;  // 或 None、Transparent 等
})
  • 动态回调,运行时决定行为

  • 可根据业务状态变化

五、事件分发流程

双响应链分发:

起始事件 (Down/Begin)
    ↓
触摸测试建立响应链
    ├── Touch事件响应链 → 分发至目标组件
    └── 手势响应链 → 手势识别与竞争

1. 事件拦截机制

  • 触摸事件拦截:阻止事件传递给后续节点

  • 手势拦截:阻止手势响应

2. 事件冒泡

  • 最内层组件开始处理

  • 逐层向父组件传递

  • 可用 stopPropagation() 终止冒泡

六、特殊组件处理

1. 禁用控制(enable)

  • 组件及子组件不进行触摸测试

  • 直接返回父组件继续测试

2. 安全组件

  • 粘贴控件、保存控件等

  • z序更高组件遮盖时,事件返回父节点

七、注意事项

1. Cancel 事件处理

  • 与 Up 事件含义相同:事件处理结束

  • 特定场景发送(如拖拽开始时)

  • 必须同时处理 Cancel 和 Up

2. 事件完整性

  • 指向性事件保证完整序列

  • 不要只处理部分事件类型

  • 比如:接收 Down 就必须接收对应的 Up/Cancel

3. stopPropagation 使用

  • 注意保持事件类型一致性

  • 避免父组件只收到部分事件

  • 导致事件不闭环的问题

八、事件响应链构建过程

分阶段流程:

1. 触摸测试开始
   ↓
2. 收集组件手势/事件
   ↓
3. 结果冒泡至父组件
   ↓
4. 父组件整合结果
   ↓
5. 形成完整响应链

九、总结和建议

1. 热区设置场景

  • 按钮需要部分区域可点击

  • 避免相邻组件误触

  • 创建非矩形响应区域

2. 命中测试控制选择

  • Default:常规交互

  • Transparent:需要事件穿透时

  • Block:独占交互时

  • None:仅作为背景容器时

3. 拦截器使用时机

  • 需要动态控制交互时

  • 根据业务状态改变响应行为

  • 替代复杂的静态配置

   ArkUI通过命中测试构建事件响应链,过程中可用热区设置、命中控制和事件拦截三种方式精细控制交互响应流程,从事件产生到回调触发全程可控。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐