OpenHarmony实战开发-多层级手势事件

news2024/12/29 2:10:44

多层级手势事件指父子组件嵌套时,父子组件均绑定了手势或事件。在该场景下,手势或者事件的响应受到多个因素的影响,相互之间发生传递和竞争,容易出现预期外的响应。

本章主要介绍了多层级手势事件的默认响应顺序,以及如何通过设置相关属性影响多层级手势事件的响应顺序。

默认多层级手势事件

触摸事件
触摸事件(onTouch事件)是所有手势组成的基础,有Down,Move,Up,Cancel四种。手势均由触摸事件组成,例如,点击为Down+Up,滑动为Down+一系列Move+Up。触摸事件具有最特殊性:

1.监听了onTouch事件的组件,若在手指落下时被触摸则均会收到onTouch事件的回调,被触摸受到触摸热区和触摸控制影响。

2.onTouch事件的回调是闭环的。若一个组件收到了手指Id为0的Down事件,后续也会收到手指Id为0的Move事件和Up事件。

3.onTouch事件的回调是一致的。若一个组件收到了手指Id为0的Down事件未收到手指Id为1的Down事件,则后续只会收到手指Id为0的touch事件,不会收到手指Id为1的后续touch事件。

对于一般的容器组件(例如:Column),父子组件之间onTouch事件能够同时触发,兄弟组件之间onTouch事件根据布局进行触发。

ComponentA() {
    ComponentB().onTouch(() => {})
    ComponentC().onTouch(() => {})
}.onTouch(() => {})

组件B和组件C作为组件A的子组件,当触摸到组件B或者组件C时,组件A也会被触摸到。onTouch事件允许多个组件同时触发, 因此,当触摸组件B时,会触发组件A和组件B的onTouch回调,不会触发组件C的onTouch回调。 当触摸组件C时,会触发组件A和组件C的onTouch回调,不触发组件B的回调。

特殊的容器组件,如Stack等组件,由于子组件之间存在着堆叠关系,子组件的布局也互相存在遮盖关系。 所以,父子组件之间onTouch事件能够同时触发,兄弟组件之间onTouch事件会存在遮盖关系。

Stack A() {
    ComponentB().onTouch(() => {})
    ComponentC().onTouch(() => {})
}.onTouch(() => {})

组件B和组件C作为Stack A的子组件,组件C覆盖在组件B上。当触摸到组件B或者组件C时,Stack A也会被触摸到。onTouch事件允许多个组件同时触发,因此,当触摸组件B和组件C的重叠区域时,会触发Stack A和组件C的onTouch回调,不会触发组件B的onTouch回调(组件B被组件C遮盖)。

手势与事件

除了触摸事件(onTouch事件)外的所有手势与事件,均是通过基础手势或者组合手势实现的。例如,拖拽事件是由长按手势和滑动手势组成的一个顺序手势。

在未显示声明的情况下,同一时间,一根手指对应的手势组中只会有一个手势获得成功从而触发所设置的回调。

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

响应优先级遵循以下条件:

1.当父子组件均绑定同一类手势时,子组件优先于父组件触发。

2.当一个组件绑定多个手势时,先达到手势触发条件的手势优先触发。

ComponentA() {
    ComponentB().gesture(TapGesture({count: 1}))
}.gesture(TapGesture({count: 1}))    

当父组件和子组件均绑定点击手势时,子组件的优先级高于父组件。 因此,当在B组件上进行点击时,组件B所绑定的TapGesture的回调会被触发,而组件A所绑定的TapGesture的回调不会被触发。

ComponentA()
.gesture(
    GestureGroup(
        GestureMode.Exclusive,
        TapGesture({count: 1}),
        PanGesture({distance: 5})
    )
)

当组件A上绑定了由点击和滑动手势组成的互斥手势组时,先达到手势触发条件的手势触发对应的回调。 若使用者做了一次点击操作,则响应点击对应的回调。若使用者进行了一次滑动操作,则响应滑动对应的回调。

自定义控制的多层级手势事件

可以通过设置属性,控制默认的多层级手势事件竞争流程,更好的实现手势事件。

目前,responseRegion属性和hitTestBehavior属性可以控制Touch事件的分发,从而可以影响到onTouch事件和手势的响应。而绑定手势方法属性可以控制手势的竞争从而影响手势的响应,但不能影响到onTouch事件。

responseRegion对手势和事件的控制
responseRegion属性可以实现组件的响应区域范围的变化。响应区域范围可以超出或者小于组件的布局范围。

ComponentA() {
    ComponentB()
    .onTouch(() => {})
    .gesture(TapGesture({count: 1}))
    .responseRegion({Rect1, Rect2, Rect3})
}
.onTouch(() => {})
.gesture(TapGesture({count: 1}))
.responseRegion({Rect4})

当组件A绑定了.responseRegion({Rect4})的属性后,所有落在Rect4区域范围的触摸事件和手势可被组件A对应的回调响应。

当组件B绑定了.responseRegion({Rect1, Rect2, Rect3})的属性后,所有落在Rect1,Rect2和Rect3区域范围的触摸事件和手势可被组件B对应的回调响应。

当绑定了responseRegion后,手势与事件的响应区域范围将以所绑定的区域范围为准,而不是以布局区域为准,可能出现布局相关区域不响应手势与事件的情况。

此外,responseRegion属性支持由多个Rect组成的数组作为入参,以支持更多开发需求。

hitTestBehavior对手势和事件的控制

hitTestBehavior属性可以实现在复杂的多层级场景下,一些组件能够响应手势和事件,而一些组件不能响应手势和事件。

ComponentA() {
    ComponentB()
    .onTouch(() => {})
    .gesture(TapGesture({count: 1}))

    ComponentC() {
        ComponentD()
        .onTouch(() => {})
        .gesture(TapGesture({count: 1}))
    }
    .onTouch(() => {})
    .gesture(TapGesture({count: 1}))
    .hitTestBehavior(HitTestMode.Block)
}
.onTouch(() => {})
.gesture(TapGesture({count: 1}))

HitTestMode.Block的效果为,自身会响应触摸测试,阻塞子节点和兄弟节点的触摸测试,从而导致子节点和兄弟节点的onTouch事件和手势均无法触发。

当组件C未设置hitTestBehavior时,点击组件D区域,组件A、组件C和组件D的onTouch事件会触发,组件D的点击手势会触发。

当组件C设置了hitTestBehavior为HitTestMode.Block时,点击组件D区域,组件A和组件C的onTouch事件会触发,组件D的onTouch事件未触发。同时,由于组件D的点击手势因为被阻塞而无法触发,组件C的点击手势会触发。

Stack A() {
    ComponentB()
    .onTouch(() => {})
    .gesture(TapGesture({count: 1}))

    ComponentC()
    .onTouch(() => {})
    .gesture(TapGesture({count: 1}))
    .hitTestBehavior(HitTestMode.Transparent)
}
.onTouch(() => {})
.gesture(TapGesture({count: 1}))

HitTestMode.Transparent的效果为,自身响应触摸测试,不会阻塞兄弟节点的触摸测试。

当组件C未设置hitTestBehavior时,点击组件B和组件C的重叠区域时,Stack A和组件C的onTouch事件会触发,组件C的点击事件会触发,组件B的onTouch事件和点击手势均不触发。

而当组件C设置hitTestBehavior为HitTestMode.Transparent时,点击组件B和组件C的重叠区域,组件A和组件C不受到影响与之前一致,组件A和组件C的onTouch事件会触发,组件C的点击手势会触发。而组件B因为组件C设置了HitTestMode.Transparent,组件B也收到了Touch事件,从而组件B的onTouch事件和点击手势触发。

ComponentA() {
    ComponentB()
    .onTouch(() => {})
    .gesture(TapGesture({count: 1}))
}
.onTouch(() => {})
.gesture(TapGesture({count: 1}))
.hitTestBehavior(HitTestMode.None)

HitTestMode.None的效果为,自身不响应触摸测试,不会阻塞子节点和兄弟节点的触摸控制。

当组件A未设置hitTestBehavior时,点击组件B区域时,组件A和组件B的onTouch事件均会触发,组件B的点击手势会触发。

当组件A设置hitTestBehavior为HitTestMode.None时,点击组件B区域时,组件B的onTouch事件触发,而组件A的onTouch事件无法触发,组件B的点击手势触发。

针对简单的场景,建议在单个组件上绑定hitTestBehavior。 针对复杂场景,建议在多个组件上绑定不同的hitTestBehavior来控制Touch事件的分发。

绑定手势方法对手势的控制
设置绑定手势的方法可以实现在多层级场景下,当父组件与子组件绑定了相同的手势时,设置不同的绑定手势方法有不同的响应优先级。

当父组件使用.gesture绑定手势,父子组件所绑定手势类型相同时,子组件优先于父组件响应。

ComponentA() {
    ComponentB()
    .gesture(TapGesture({count: 1}))
}
.gesture(TapGesture({count: 1}))

当父子组件均正常绑定点击手势时,子组件优先于父组件响应。 此时,单击组件B区域范围,组件B的点击手势会触发,组件A的点击手势不会触发。

如果以带优先级的方式绑定手势,则可使得父组件所绑定手势的响应优先级高于子组件。

ComponentA() {
    ComponentB()
    .gesture(TapGesture({count: 1}))
}
.priorityGesture(TapGesture({count: 1}))

当父组件以.priorityGesture的形式绑定手势时,父组件所绑定的手势优先级高于子组件。 此时,单击组件B区域范围,组件A的点击手势会触发,组件B的点击手势不会触发。

如果需要父子组件所绑定的手势不发生冲突,均可响应,则可以使用并行的方式在父组件绑定手势。

ComponentA() {
    ComponentB()
    .gesture(TapGesture({count: 1}))
}
.parallelGesture(TapGesture({count: 1}))

当父组件以.parallelGesture的形式绑定手势时,父组件和子组件所绑定的手势均可触发。 此时,单击组件B区域范围,组件A和组件B的点击手势均会触发。

如果大家还没有掌握鸿蒙,现在想要在最短的时间里吃透它,我这边特意整理了《鸿蒙语法ArkTS、TypeScript、ArkUI等…视频教程》以及《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

鸿蒙语法ArkTS、TypeScript、ArkUI等…视频教程:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

OpenHarmony APP开发教程步骤:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

《鸿蒙开发学习手册》:

如何快速入门:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.基本概念
2.构建第一个ArkTS应用
3.……

在这里插入图片描述

开发基础知识:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

在这里插入图片描述

基于ArkTS 开发:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

在这里插入图片描述

鸿蒙生态应用开发白皮书V2.0PDF:https://docs.qq.com/doc/DZVVkRGRUd3pHSnFG

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1630940.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL8.0 msi版本安装教程

MySQL8.0 msi 版本安装教程 1> 官网下载安装包 2> 安装MySQL 2.1双击打开下载的安装包,进入到下面这个页面,选择 Custom 选项,之后,点击next 说明: 2.2 选择所需产品,更改安装位置(当然也可以默认安…

公式SUM(A2:C4C2:D5)一共对几个单元格进行求和?

一、公式中的几个问题 1.括号和冒号是双字节的字符。 这个不用多说了,相信题主中是提问时书写笔误,实际在Excel中写公式时肯定用的是英文单字节字符。 2.括号里是两个区域, 但两个区域之间是怎样的运算关系并没有说,或者说是遗…

数据结构之顺顺顺——顺序表

1.浅谈数据结构 相信我们对数据结构都不陌生,我们之前学过的数组就是最基础的数据结构,它大概就长这样: 数组 而作为最简单的数据结构,数组只能帮助我们实现储存数据这一个功能,随着学习的深入,和问题的日渐…

远程控制软件优化(1)

远程控制软件优化(1) 第一版存在以下缺点: 1、四大部分中 Robot States 部分过于简陋,不适合放到论文中 2、Lidar BEV 图像显示效果非常差,显示不全且很稀疏 3、视频流传输延时过高,无法实现远程控制 以…

学python的第二十三天

原文链接:Python 图形化界面设计(Tkinter) - 简书 (jianshu.com) 子窗体(Toplevel) 直接上代码: # 子窗体 from tkinter import *def newwindow():winNew Toplevel(root)winNew.geometry(320x240)winNe…

C语言-atoi和atof函数的使用

人生应该树立目标,否则你的精力会白白浪费。💓💓💓 目录 •🌙知识回顾 🍋知识点一:atoi函数的使用和实现 • 🌰1.函数介绍 • 🌰2.代码演示 • 🌰3.atoi函数的…

《十一》Qt各种对话框之QInputDialog

QInputDialog QInputDialog 用于方便快捷地获取一个用户输入数据,支持整数 int、浮点数 double、文本 QString 三种数据。按照 QInputDialog 内部的输入控件,又可以分为整数输入控件 QSpinBox、浮点数输入控件 QDoubleSpinBox、单行文本输入控件 QLineE…

AI大模型日报#0428:AI聊天半年涨粉1000万、元象发布多模态XVERSE-V、字节发布视觉ViTamin

导读: 欢迎阅读《AI大模型日报》,内容基于Python爬虫和LLM自动生成。目前采用“文心一言”生成了每条资讯的摘要。AI大模型日报今日要点: 今日,AI大模型领域动作频频,多家科技巨头和初创公司展示了其最新研发成果。快手…

暗区突围如何申请测试资格?暗区突围测试申请的方法轻松掌握

游戏中健康系统与其它射击游戏有很大区别,根据受伤部位、伤势的不同,会有不同的表现。除了头部之外,其它部位如果损坏后继续受到伤害,那么伤害将会分摊到身体其它部位。在暗区内或者暗区外都可以对角色进行治疗,角色不…

FebHost:深入分析企业海外市场选通用域名还是国别域名?

企业想进入海外在线市场,非常重要的一个环节是如何选择一个在线品牌域名,很多企业面临着选择.COM还是国别域名。以下是一些需要考虑的因素。 域名可用性 一个网站的域名可以给人留下深刻的品牌印象。新企业更倾向于选择 .com、.net 和 .org 等标准通用顶…

【哔哩哔哩笔试题汇总】2024-04-28-哔哩哔哩春招笔试题-三语言题解(CPP/Python/Java)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新b站近期的春秋招笔试题汇总~ 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢&#x1f497…

由于找不到msvcr120.dll,无法继续执行代码

在日常编程中,缺少关键的msvcr120.dll文件可能会导致代码无法执行,给我们带来不便。针对缺少msvcr120.dll文件的情况,我们可以采取一些有效的解决方法来解决这一问题。通过下载安装或使用Visual C Redistributable工具安装该msvcr120.dll文件…

MySQL/MariaDB 如何查看当前的用户

MySQL 的所有数据库用户信息是存储在 user 数据表中的。 可以在登录成功数据后运行 SQL: MariaDB [(none)]> select user,host from user;就可以查看到数据中的所有用户信息。 MariaDB [(none)]> select user,host from user; ERROR 1046 (3D000): No databa…

K8S哲学 - statefulSet 灰度发布

kubectl get - 获取资源及配置文件 kubectl get resource 【resourceName -oyaml】 kubectl create - 指定镜像创建或者 指定文件创建 kubectl create resource 【resourceName】 --imagemyImage 【-f my.yaml】 kubectl delete kubectl describe resource resourc…

医院敏感文件交互 如何保障安全和效率?

医院会产生大量的敏感文件,这些敏感文件交互时,都需要使用特殊的手段,来保障数据的安全性。 医院的敏感数据主要包括以下几类: 1、患者基本信息:包括患者的姓名、身份证号码、户籍地或现住址、联系方式、文化程度、既…

LeetCode - LCR 179.查找总价格为目标值的两个商品

一. 题目链接 LeetCode - LCR 179. 查找总价格为目标值的两个商品 解法(双指针 - 对撞指针): 算法思路: 注意到本题是升序的数组,因此可以用「对撞指针」优化时间复杂度。 算法流程: 初始化left &#…

el-form 表单设置某个参数非必填验证

html <el-form ref"form" :rules"rules"><el-form-item prop"tiktokEmail" label"邮箱" ><el-input v-model"form.tiktokEmail" placeholder"邮箱" ></el-input></el-form-item&…

一篇了解reactor框架特性

一篇了解reactor框架特性 本文档的一些典型的名词如下&#xff1a; Publisher&#xff08;发布者&#xff09;、Subscriber&#xff08;订阅者&#xff09;、Subscription&#xff08;订阅 n.&#xff09;、subscribe&#xff08;订阅 v.&#xff09;。event/signal&#xff0…

一文搞懂 One-Hot Encoding(独热编码)

文章目录 前言 1、独热编码的原理 2、独热编码的分类 3、独热编码的应用 前言 本文将从独热编码的原理、独热编码的分类、独热编码的应用三个方面&#xff0c;来展开介绍独热编码 One-Hot Encoding。 1、独热编码的原理 特征数字化&#xff1a;将分类变量&#xff08;或称为离…

手机测试之-adb

一、Android Debug Bridge 1.1 Android系统主要的目录 1.2 ADB工具介绍 ADB的全称为Android Debug Bridge,就是起到调试桥的作用,是Android SDK里面一个多用途调试工具,通过它可以和Android设备或模拟器通信,借助adb工具,我们可以管理设备或手机模拟器的状态。还可以进行很多…