首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

  • 24-12-02 22:27
  • 2184
  • 10036
juejin.cn

事件响应链收集

  1. 触摸事件(onTouch事件)是用户与设备交互的原始事件,是所有手势事件组成的基础,有Down,Move,Up,Cancel四种触摸事件的类型。 手势均由触摸事件组成

  2. 触摸事件的分发由触摸测试(TouchTest)结果决定,其结果会直接决定哪些控件的事件加入事件响应链(事件响应成员组成的链表),并最终按照响应链顺序判定是否消费

有几个因素可以影响触摸测试的结果

  • TouchTest:触摸测试入口方法,此方法无外部接口
    • TouchTest的触发时机由每次点按的按下动作发起,默认由组件树的根节点的TouchTest方法作为入口
    • hitTestBehavior可以由InterceptTouch事件变更
    • 触摸热区/禁用控制等不满足组件事件交互诉求,会导致立即返回父节点

image.png

  • hitTestBehavior:触摸测试控制

    • 命中:触摸测试成功收集到当前组件/子组件的事件。
    • 子组件对父组件触摸测试的影响,取决于最后一个没有被阻塞触摸测试的子组件
    • HitTestMode.Default:默认不配hitTestBehavior属性的效果,自身如果命中会阻塞兄弟组件,但是不阻塞子组件。

    • HitTestMode.None:自身不接收事件,但不会阻塞兄弟组件/子组件继续做触摸测试。

    • HitTestMode.Block:阻塞子组件的触摸测试,如果自身触摸测试命中,会阻塞兄弟组件及父组件的触摸测试。

    • HitTestMode.Transparent:自身进行触摸测试,同时不阻塞兄弟组件及父组件。

  • interceptTouch:事件自定义拦截

    • 自定义事件拦截在按下触发时,可以根据业务状态 动态改变组件的hitTestBehavior属性
  • responseRegion:触摸热区设置

    • 触摸热区设置会影响触屏/鼠标类的触摸测试,如果设置为0,或不可触控区域,则事件直接返回父节点继续触摸测试
  • enabled:禁用控制

    • 设置禁用控制的组件,包括其子组件不会发起触摸测试过程,会直接返回父节点继续触摸测试
  • 安全组件

    • ArkUI包含的安全组件有:使用位置组件、使用粘贴组件、使用保存组件等。

    • 安全组件当前对触摸测试影响:如果有组件的z序比安全组件的z序靠前,且遮盖安全组件,则安全组件事件直接返回到父节点继续触摸测试

  • 其他属性设置:透明度/组件下线

点击查看 具体怎么影响触摸测试结果

  1. ArkUI事件响应链收集,根据右子树(按组件布局的先后层级)优先的后序遍历流程

例如 用户触摸的动作如果发生在组件E上,事件响应链收集的流程如下

  • 根据右子树优先的后序遍历流程,所以事件会从右边树的D节点开始往上传。
  • 虽然触摸点在组件D和组件B的交集上,但组件D的hitTestBehavior属性默认为HitTestMode.Default,D组件收集到事件后会阻塞兄弟节点(组件B)
  • 所以没有收集组件A的左子树,最终收集到的响应链是E->D->A。

ArkUI在处理触屏事件时,会在触屏事件触发前进行按压点和组件区域的触摸测试,来收集需要响应触屏事件的组件

再基于触摸测试结果分发相应的触屏事件

手势

手势分为系统手势和自定义手势,系统手势的优先级更高,会被优先响应

除了触摸事件(onTouch事件)外的所有手势与事件,均是通过基础手势或者组合手势实现的。

除非显式声明允许多个手势同时成功,否则同一时间只会有一个手势响应。

  1. 当父子组件均绑定同一类手势时,子组件优先于父组件触发。
  2. 当同一个组件同时绑定多个手势时,先达到手势触发条件的手势优先触发。
  3. 当同一个组件绑定相同事件类型的系统手势和自定义手势时,系统手势会优先响应

手势响应优先级(从左至右,优先级由高到低) image.png

手势绑定

通过绑定手势方法绑定不同的手势,可以影响对手势响应的控制

手势绑定支持 常规手势绑定方法(gesture)、带优先级手势绑定方法(priorityGesture)、并行手势绑定方法(parallelGesture)

绑定手势方法功能规格配参1配参2约束
gesture绑定手势事件,父子组件交叠区域均绑定,响应子组件GestureTypeGestureMask与通用事件抢占
priorityGesture当父组件配置priorityGesture时,优先识别父组件priorityGesture绑定的手势。GestureTypeGestureMask与通用事件抢占
parallelGesture父组件绑定parallelGesture时,父子组件相同的手势事件都可以触发GestureTypeGestureMask无

加入priorityGesture和parallelGesture绑定方法后,手势的响应顺序 image.png

GestureMask枚举说明

名称描述
Normal不屏蔽子组件的手势,按照默认手势识别顺序进行识别。
IgnoreInternal屏蔽子组件的手势,包括子组件上的系统内置的手势,如子组件为List组件时,内置的滑动手势同样会被屏蔽。 若父子组件区域存在部分重叠,则只会屏蔽父子组件重叠的部分。

不同手势绑定配参方案规格

父手势子手势GestureMask(父)交叠区域相同事件响应方交叠区域不同事件响应方
gesturegesturedefault子组件各自响应
gesturegestureIgnoreInternal父组件父组件
priorityGesturegesturedefault父组件各自响应
priorityGesturegestureIgnoreInternal父组件父组件
parallelGesturegesturedefault各自响应各自响应
parallelGesturegestureIgnoreInternal父组件父组件

组合手势(GestureGroup)

手势组合是指多种手势组合为复合手势,通过GestureGroup属性,可以给同一个组件添加多个手势,支持连续识别、并行识别和互斥识别模式

组合手势属于手势的一种,也会影响手势响应的控制

接口可选模式描述注册事件
GestureGroupSequence手势顺序队列,需要按预定的手势组顺序执行,有一个失败则全部失败onCancel
GestureGroupParallel手势组合,直到所有已识别的手势执行完无
GestureGroupExclusive互斥识别,成功完成一个手势,则完成手势任务无

独占事件控制

通过monopolizeEvents属性设置组件是否独占事件,事件范围包括组件自带的事件和开发者自定义的点击、触摸、手势事件。先响应事件的控件作为第一响应者,在手指离开屏幕前其他组件不会响应任何事件。

在一个窗口内,设置了独占控制的组件上的事件如果首先响应,则本次交互只允许此组件上设置的事件响应,窗口内其他组件上的事件不会响应。

如果开发者通过parallelGesture绑定了与子组件同时触发的手势,如PanGesture,子组件设置了独占控制且首个响应事件,则父组件的手势不会响应。

自定义手势判定

为组件提供自定义手势判定能力。开发者可根据需要,在手势识别期间,根据自己的业务逻辑来决定是否响应手势。使用onGestureJudgeBegin方法对手势进行判定,开发者可以根据自身业务逻辑,选择是否响应自定义手势。

手势拦截增强

通过shouldBuiltInRecognizerParallelWith将系统内置手势和比其优先级高的手势做并行化处理,可以动态控制手势事件的触发(这里主要是系统的Pan手势)

responseRegion和hitTestBehavior

影响触摸测试的因素同样也可能会影响到手势的响应流程。例如responseRegion属性和hitTestBehavior属性可以控制Touch事件的分发,从而可以影响到onTouch事件和手势的响应。而绑定手势方法属性可以控制手势的竞争从而影响手势的响应,但不会影响到onTouch事件。

ArkUI组件自身的属性控制手势响应

ArkUI组件自身的属性,也可以对手势事件的响应做出控制。例如Grid、List、Scroll、Swiper、WaterFlow等滚动容器组件提供了nestedScroll属性,来解决和父组件的嵌套滚动的冲突问题;例如Swiper组件的disableSwipe可以设置禁用组件滑动切换的功能;又例如List组件可以通过设置enableScrollInteraction属性来设置是否支持手势滚动列表。

其它影响触摸测试的API

  1. 在父节点,通过onChildTouchTest决定如何让子节点去做触摸测试,影响子组件的触摸测试,最终影响后续的触屏事件分发
  2. 在组件节点自身,通过onTouchIntercept来根据事件在控件上按下时发生的位置、输入源等事件信息决定控件上的HitTestMode属性

源码处理流程

我们可以在 arkcompiler_ets_runtime源码中找到TouchTest的处理流程 gitee.com/openharmony…

HitTestResult FrameNode::TouchTest(const PointF& globalPoint, const PointF& parentLocalPoint, const PointF& parentRevertPoint, TouchRestrict& touchRestrict, TouchTestResult& result, int32_t touchId, ResponseLinkResult& responseLinkResult, bool isDispatch)

梳理后的流程图大概如下 Untitled.png

onGestureRecognizerJudgeBegin和onGestureJudgeBeginCallback互斥,并且onGestureRecognizerJudgeBegin的优先级更高 image.png

参考资料

  1. 自定义事件拦截 onTouchIntercept developer.huawei.com/consumer/cn…
  2. 自定义事件分发 onChildTouchTest developer.huawei.com/consumer/cn…
  3. 自定义手势判定 onGestureJudgeBegin developer.huawei.com/consumer/cn…
  4. 手势拦截增强 shouldBuiltInRecognizerParallelWith developer.huawei.com/consumer/cn…
  5. 触摸测试 developer.huawei.com/consumer/cn…
  6. 事件独占控制 monopolizeEvents developer.huawei.com/consumer/cn…
  7. 触摸热区设置 responseRegion developer.huawei.com/consumer/cn…
  8. 触摸测试控制 hitTestBehavior developer.huawei.com/consumer/cn…
  9. 手势事件冲突解决方案 developer.huawei.com/consumer/cn…
  10. ArkTS运行时源码 gitee.com/openharmony…
注:本文转载自juejin.cn的HarderCoder的文章"https://juejin.cn/post/7441857319639580698"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

141
iOS
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top