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

HarmonyOS7 拖拽方向限制:PanDirection 让组件只能水平或垂直拖动

文章目录

    • 前言
    • 方案对比表
    • 详细实现
      • 水平拖拽
      • 垂直拖拽
    • 完整代码
    • 优劣分析
    • 实际案例
      • 侧滑删除
      • 下拉刷新
    • 写在最后

前言

上篇文章讲了自由拖拽——方块可以往任何方向移动。但实际场景中,很多时候我们需要限制拖拽方向。比如:

  • 音量滑块只能水平拖动
  • 下拉刷新只能垂直拖动
  • 侧滑删除只能水平拖动

PanGesturedirection参数就是用来限制拖拽方向的。

方案对比表

PanDirection提供了以下枚举值:

说明适用场景
All所有方向自由拖拽
Horizontal仅水平滑块、轮播
Vertical仅垂直下拉、列表排序
Left仅向左右滑删除
Right仅向右左滑展开

|Up| 仅向上 | 上滑关闭 |
|Down| 仅向下 | 下拉刷新 |

详细实现

水平拖拽

@StatehOffsetX:number=0@StatehPosX:number=0Stack(){Row(){Column(){Text('← →').fontSize(18).fontColor('#FFFFFF')}.width(70).height(50).backgroundColor('#4D96FF').borderRadius(12).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center).offset({x:this.hOffsetX,y:0}).gesture(PanGesture({direction:PanDirection.Horizontal}).onActionUpdate((event:GestureEvent)=>{this.hOffsetX=this.hPosX+event.offsetX}).onActionEnd(()=>{this.hPosX=this.hOffsetX}))}}.width('100%').height(60).backgroundColor('#F8F8F8').borderRadius(10)

关键点:

  • direction: PanDirection.Horizontal— 只响应水平方向的拖拽
  • .offset({ x: this.hOffsetX, y: 0 })— Y 轴固定为 0,只在 X 轴移动
  • onActionUpdate只使用event.offsetX,忽略event.offsetY

用户上下拖动手指时,方块不会有反应——只有左右拖动才会移动。

垂直拖拽

@StatevOffsetY:number=0@StatevPosY:number=0Stack(){Column(){Column(){Text('↑ ↓').fontSize(18).fontColor('#FFFFFF')}.width(70).height(50).backgroundColor('#6BCB77').borderRadius(12).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center).offset({x:0,y:this.vOffsetY}).gesture(PanGesture({direction:PanDirection.Vertical}).onActionUpdate((event:GestureEvent)=>{this.vOffsetY=this.vPosY+event.offsetY}).onActionEnd(()=>{this.vPosY=this.vOffsetY}))}}.width('100%').height(60).backgroundColor('#F8F8F8').borderRadius(10)

垂直拖拽跟水平拖拽的写法完全对称——direction改成Vertical.offset()的 X 固定为 0,使用event.offsetY

完整代码

@Entry@Componentstruct PanGestureDirection{@StatehOffsetX:number=0@StatehPosX:number=0@StatevOffsetY:number=0@StatevPosY:number=0build(){Column(){Column(){Text('拖拽方向限制').fontSize(16).fontWeight(FontWeight.Bold).margin({bottom:16})// 水平拖拽Text('水平拖拽(Horizontal)').fontSize(14).fontColor('#666666').margin({bottom:8})Stack(){Row(){Column(){Text('← →').fontSize(18).fontColor('#FFFFFF')}.width(70).height(50).backgroundColor('#4D96FF').borderRadius(12).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center).offset({x:this.hOffsetX,y:0}).gesture(PanGesture({direction:PanDirection.Horizontal}).onActionUpdate((event:GestureEvent)=>{this.hOffsetX=this.hPosX+event.offsetX}).onActionEnd(()=>{this.hPosX=this.hOffsetX}))}}.width('100%').height(60).backgroundColor('#F8F8F8').borderRadius(10)// 垂直拖拽Text('垂直拖拽(Vertical)').fontSize(14).fontColor('#666666').margin({bottom:8})Stack(){Column(){Column(){Text('↑ ↓').fontSize(18).fontColor('#FFFFFF')}.width(70).height(50).backgroundColor('#6BCB77').borderRadius(12).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center).offset({x:0,y:this.vOffsetY}).gesture(PanGesture({direction:PanDirection.Vertical}).onActionUpdate((event:GestureEvent)=>{this.vOffsetY=this.vPosY+event.offsetY}).onActionEnd(()=>{this.vPosY=this.vOffsetY}))}}.width('100%').height(60).backgroundColor('#F8F8F8').borderRadius(10)}.width('100%').padding(24).backgroundColor('#FFFFFF').borderRadius(12)}.width('100%').height('100%').backgroundColor('#F5F6FA').padding(16)}}

优劣分析

限制方向的优势:

  • 防止误操作——用户无意中的斜向滑动不会干扰目标方向的拖拽
  • 交互语义更清晰——水平就是水平,垂直就是垂直
  • 简化偏移计算——只需要处理一个轴的数据

限制方向的劣势:

  • 系统判断方向需要一定的拖拽距离,可能导致初始响应有延迟
  • 用户手指的实际滑动轨迹很少有绝对水平或垂直的,系统需要做方向判定

实际案例

侧滑删除

.gesture(PanGesture({direction:PanDirection.Left}).onActionUpdate((event:GestureEvent)=>{this.slideOffset=Math.max(-80,event.offsetX)}).onActionEnd(()=>{if(this.slideOffset<-40){this.slideOffset=-80// 展开删除按钮}else{this.slideOffset=0// 收回}}))

下拉刷新

.gesture(PanGesture({direction:PanDirection.Down}).onActionUpdate((event:GestureEvent)=>{this.pullDistance=Math.min(100,event.offsetY)}).onActionEnd(()=>{if(this.pullDistance>60){this.refreshData()}this.pullDistance=0}))

写在最后

PanDirection让拖拽手势变得精确可控。水平拖拽配水平方向的限制,垂直拖拽配垂直方向的限制——方向明确,交互才清晰。

在实际项目中,90% 的拖拽场景都需要限制方向。自由拖拽虽然酷,但大多数时候用户不需要(也不想要)一个可以到处乱拖的组件。

http://www.cnnetsun.cn/news/3554498.html

相关文章:

  • Python ctypes实战:轻松调用C动态库提升性能50倍
  • Java代码审计:常见安全漏洞与防护实践
  • WSL保活机制与实战解决方案
  • 服务业消费复苏趋势与创新策略分析
  • SolidWorks建模到3D打印:解决外壳装配误差的DFM实战指南
  • 高精度ADC电路设计:阻抗匹配与抗混叠滤波实战
  • NPO光互连与分布式解耦架构在千卡GPU集群中的应用
  • Java代码规范实战:阿里巴巴开发手册核心要点解析
  • Grok CLI重大更新:命令行集成大模型,提升开发自动化效率
  • 行为AI在企业安全防御中的应用与实施
  • 嵌入式LCD控制器驱动开发:从寄存器配置到时序调试实战
  • 南京大学蒋炎岩操作系统笔记(p4-p7)
  • G-Helper终极指南:轻量级华硕笔记本控制工具,让性能与续航完美平衡
  • 基于MediaPipe的人体姿态检测与相似性搜索:如何实现精准的动作匹配系统
  • 5分钟搭建京东抢购脚本:告别手动秒杀烦恼的终极指南
  • HALCON 图像平滑处理算子原理解释与用处
  • 京东抢购自动化终极指南:JDspyder脚本让秒杀成功率翻倍
  • JAVAEE初阶 --- 构造HTTP请求
  • 计算机毕业设计之校园运动会管理系统
  • AI大模型学习路线:从入门到精通的系统化路径
  • OpenClaw Token优化:5大配置节省50%成本
  • C++编程入门:从环境配置到函数核心的实战指南
  • Intel NPU C++ API编译实战:从环境配置到CMake排坑指南
  • C++实现计算机功能:从编译器到内存管理的核心原理与实践
  • 手把手实现象棋AI:从数据结构到Alpha-Beta剪枝的完整项目实战
  • 服务器磁盘一夜写满 100GB,根因是一行 DEBUG 日志
  • 深入解析AM263P ADC高级特性:中断溢出、PPB与安全检查器实战
  • Unity整合KinectForUnity 2.9插件:体感交互开发全流程指南
  • 深入解析红黑树在TreeMap中的实现与应用
  • TMS320F28004x DMA模块架构解析与驱动开发实战