当前位置: 首页 > news >正文

HarmonyOS7 手势综合展示:六种手势类型一网打尽 + Grid 数据看板

文章目录

    • 前言
    • 效果展示
    • 方案设计
      • 多层手势共存策略
    • 详细实现
      • 状态变量
      • 日志函数
      • Grid 统计看板
      • statCard Builder
      • 三层手势绑定
      • 滑动方向判定
      • 日志面板
    • 踩坑记录
    • 写在最后

前言

前面十几篇文章分别讲了 ArkUI 的各种手势类型,今天来一个"全家桶"——把点击、长按、双击、拖拽、缩放、旋转、滑动全部集成到一个界面里,用 Grid 布局做数据看板,实时显示每种手势的触发次数和状态。这篇文章既是手势系列的总结,也是一个手势调试工具的设计参考。

效果展示

界面分三个区域:

  1. 统计看板:6 个 Grid 格子,分别显示点击/长按/双击/滑动/拖拽/缩放的计数或状态

  1. 测试区域:一个大色块,支持所有手势操作
  2. 日志面板:记录最近 8 条手势操作的时间线

方案设计

多层手势共存策略

一个组件上要同时支持 7 种手势,怎么组织?答案是分三层

层级手势模式
第一层双击、单击、长按Exclusive(互斥)
第二层拖拽、缩放、旋转Parallel(并行)

| 第三层 | 快速滑动 | 独立绑定 |

三层手势用三个.gesture()调用分别绑定。ArkUI 允许多次调用.gesture(),后面的不会覆盖前面的。

详细实现

状态变量

@Entry@Componentstruct GestureShowcase{@StatetapCount:number=0@StatelongPressCount:number=0@StateswipeDirection:string='-'@StatepanOffset:string='(0, 0)'@StatescaleValue:number=1@StateangleValue:number=0@StatedoubleTapCount:number=0@StategestureLog:string[]=[]// ...}

每种手势对应一个状态变量,gestureLog记录操作日志。

日志函数

logGesture(name:string){consttime=newDate().toLocaleTimeString()this.gestureLog.unshift(`[${time}]${name}`)if(this.gestureLog.length>8){this.gestureLog.pop()}}

每次手势触发时调用,新日志插入数组头部,超过 8 条就移除最旧的。unshift+pop组合实现了固定长度的 FIFO 队列。

Grid 统计看板

Grid(){GridItem(){this.statCard('点击',`${this.tapCount}`,'#4D96FF')}GridItem(){this.statCard('长按',`${this.longPressCount}`,'#FF6B6B')}GridItem(){this.statCard('双击',`${this.doubleTapCount}`,'#9B59B6')}GridItem(){this.statCard('滑动',this.swipeDirection,'#6BCB77')}GridItem(){this.statCard('拖拽',this.panOffset,'#FFA500')}GridItem(){this.statCard('缩放',`${Math.floor(this.scaleValue*100)}%`,'#4ECDC4')}}.columnsTemplate('1fr 1fr 1fr').rowsTemplate('1fr 1fr').rowsGap(8).columnsGap(8).width('100%').height(160).margin({bottom:16})

3 列 2 行的 Grid 布局,每个格子用@Builder函数statCard统一渲染。

statCard Builder

@BuilderstatCard(label:string,value:string,color:string){Column(){Text(value).fontSize(18).fontWeight(FontWeight.Bold).fontColor(color)Text(label).fontSize(10).fontColor('#999999').margin({top:2})}.width('100%').height('100%').backgroundColor('#F8F8F8').borderRadius(8).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)}

@Builder是 ArkUI 的自定义构建函数,可以在组件的build()方法里调用。这里传入标签、数值和颜色,生成统一风格的统计卡片。

三层手势绑定

Column(){Text('手势测试区域').fontSize(16).fontColor('#FFFFFF')Text('点击/长按/双击/拖动/缩放/旋转').fontSize(11).fontColor('#FFFFFF').opacity(0.8)}.width('100%').height(140).backgroundColor('#667eea').borderRadius(16).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center).scale({x:this.scaleValue,y:this.scaleValue}).rotate({angle:this.angleValue})// 第一层:互斥手势.gesture(GestureGroup(GestureMode.Exclusive,TapGesture({count:2}).onAction(()=>{this.doubleTapCount++this.logGesture('双击')}),TapGesture({count:1}).onAction(()=>{this.tapCount++this.logGesture('单击')}),LongPressGesture({duration:500}).onAction(()=>{this.longPressCount++this.logGesture('长按')})))// 第二层:并动手势.gesture(GestureGroup(GestureMode.Parallel,PanGesture({direction:PanDirection.All}).onActionUpdate((event:GestureEvent)=>{this.panOffset=`(${Math.floor(event.offsetX)},${Math.floor(event.offsetY)})`}).onActionEnd(()=>{this.logGesture('拖拽')}),PinchGesture({fingers:2}).onActionUpdate((event:GestureEvent)=>{this.scaleValue=event.scale}).onActionEnd(()=>{this.logGesture('缩放')}),RotationGesture({fingers:2}).onActionUpdate((event:GestureEvent)=>{this.angleValue=event.angle}).onActionEnd(()=>{this.logGesture('旋转')})))// 第三层:滑动手势.gesture(SwipeGesture({direction:SwipeDirection.All}).onAction((event:GestureEvent)=>{constangle=event.angle??0if(angle>=45&&angle<135)this.swipeDirection='↑'elseif(angle>=135&&angle<225)this.swipeDirection='←'elseif(angle>=225&&angle<315)this.swipeDirection='↓'elsethis.swipeDirection='→'this.logGesture('滑动')}))

这段代码是手势系列知识的大综合。注意scalerotate直接绑在组件上,缩放和旋转操作能实时看到效果。

滑动方向判定

constangle=event.angle??0if(angle>=45&&angle<135)this.swipeDirection='↑'elseif(angle>=135&&angle<225)this.swipeDirection='←'elseif(angle>=225&&angle<315)this.swipeDirection='↓'elsethis.swipeDirection='→'

把 360° 分成四个 90° 的扇区,每个扇区对应一个方向。比之前的"左/右"二分法更精细。

日志面板

Column(){Text('手势日志').fontSize(13).fontWeight(FontWeight.Bold).margin({bottom:8})ForEach(this.gestureLog,(log:string)=>{Text(log).fontSize(11).fontColor('#999999').margin({bottom:2})})}.width('100%').margin({top:16}).padding(12).backgroundColor('#F8F8F8').borderRadius(8)

时间戳 + 手势名称的列表,最多 8 条。类似开发者工具的日志面板。

踩坑记录

问题原因解决
双击不触发被单击"抢走"了双击写在单击前面(Exclusive 模式按顺序判定)
拖拽和滑动冲突两者都是水平/垂直滑动用速度区分:SwipeGesture 有速度阈值
缩放后面板数字跳动缩放影响了布局只影响测试区域,不影响统计面板

多次调用.gesture()时,手势之间的优先级取决于绑定顺序。先绑定的优先级高。如果发现某种手势"死活触发不了",检查一下是不是被另一个手势"抢"了。

写在最后

这个综合案例把手势系列的所有知识点串在了一起。核心设计思路是"分层管理"——互斥的放一层,并行的放一层,独立的放一层。配合 Grid 看板和日志面板,不仅能验证手势是否正常工作,还能直观看到每种手势的触发情况。

做手势密集的界面时,建议也做一个类似的调试面板,开发效率会高很多。

http://www.jsqmd.com/news/1250423/

相关文章:

  • vscode C++ qmake 配置问题
  • 什么是双向鉴权?从一个随机数说起
  • 青岛专业工程律师于臻:政府及国企拖欠工程款应如何依法处理 - 新思维商业观察
  • 白帽SEO服务商平台推荐:白帽技术趋势2026与合规优化机构盘点 - GEORANK
  • zynq高频小数据量PS闭环的三个实验-第3课:Linux驱动测试
  • 2026食品塑料容器行业格局调研|京津冀优质厂商综合实力分析分析,密封塑料桶/大批量注塑加工,食品塑料容器源头厂家推荐 - 品牌推荐师
  • 51单片机从零到实战(13)——毕设常用ADC模块
  • Python模块管理的底层逻辑:从路径查询到版本溯源
  • Q-learning在机器人迷宫路径规划中的Matlab实现
  • 2026桌面Agent实测:17款工具盘点、避坑指南与未来趋势
  • 基于YOLOv11的水稻病虫害智能检测系统开发实践
  • CANN开源仓与AIGC技术融合:架构解析与性能优化
  • 【高清视频】M.2 SSD 到底有没有进入 L1.2低功耗?Quarch PAM 同时看清功耗与 CLKREQ#
  • HarmonyOS7 多指触控追踪:onTouch 事件与 TouchEvent 详解
  • 椰林海鲜码头企业新愿景是什么?:笃信开创未来 - 17728181569
  • 国内知名SEO优化公司 正规平台:具备GEO优化资质的知名SEO正规服务平台盘点 - GEORANK
  • 基于YOLOv10的体育场馆设备智能检测系统设计与实现
  • 2026大连市防水补漏维修公司口碑实测推荐 - 鼎万建筑修缮
  • 从聊天工具到开发系统:ChatGPT、Codex、Plus与Pro正在重新分工
  • 智能体来了:AI大模型工具深度运用指南——从ChatGPT高级玩法到AI智能体搭建教程全面解析
  • AI办公指令实战:提升效率的自动化技巧
  • 大型SEO服务商vs独立SEO工作室:优缺点全面对比与企业适配指南 - GEORANK
  • 抖音去水印在线工具哪个好用?2026 年还稳不稳 一份个人收藏学习向实测 - 免费软件工具方法教程
  • TVA驱动的具身智能迭代逻辑(9)
  • 深圳设备搬运公司福田区:电梯设备搬运+安装调试避坑指南,房地产项目搬迁要点 - szxybj
  • 2026正规的太原防水补漏公司实测推荐 - 鼎万建筑修缮
  • 大模型开发入门指南:从零基础到实战精通
  • 杭州品牌出海GEO服务商代理加盟选型哪家靠谱?2026年杭州GEO代理服务商本地推荐与加盟指南 - 小随科技
  • 【从0搭建AI智能体·11】把 Agent 部署上线:Docker + 限流 + 熔断 + 优雅降级
  • 2026免费一键去图片水印APP推荐(安卓iOS)与在线网站合集 - 免费软件工具方法教程