当前位置: 首页 > 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.jsqmd.com/news/1233346/

相关文章:

  • LangChain实战:构建具备RAG与Agent能力的智能应用
  • 系统行为设计:从状态跃迁到可观测契约的工程实践
  • 非标定制球墨铸铁管件供应商 - 中媒介
  • Python条件判断详解:从基础语法到实战技巧
  • 万德高科网关管理软件PLC数据采集使用教程——2.0西门子S7-200-SMART的数采全流程
  • ArrayList:你手机里那个“无限容量且秒翻页”的智能订单列表
  • 真实传播的力量:从语言风格到受众心理分析
  • 2020年2月疫情热词解析与社会记忆
  • 弧形设计哪家专业? - 中媒介
  • 零基础入门PLC编程:从理论到实践的全方位指南
  • 粮油供应商的售后服务响应速度快吗? - 中媒介
  • C语言30天零基础速成:从语法到实战接单全路径解析
  • C++任意进制转换:从数学原理到工程实现与竞赛实战
  • Unity编辑器功能解锁技术原理与实现深度解析
  • Unity主程成长路线:从脚本到架构的5个关键跃迁点
  • 搜狗C++ Workflow安装配置与项目集成实战指南
  • 56.嵌入式中断与主循环解耦设计:生产消费模式完整实现
  • C++容器全面解析:从底层原理到实战选型与性能优化
  • 由近及远的智慧:深入理解不透明物体(Opaque)的绘制顺序
  • HarmonyOS7 双指缩放手势:PinchGesture 实现组件放大缩小
  • 卫生巾哪家用户体验好? - 中媒介
  • 电机技术咨询哪家推荐? - 中媒介
  • 专利无效代理哪家专业? - 中媒介
  • 足球资讯自动化采集与本地化处理实践
  • 鸿蒙Flutter DecoratedBox装饰容器:前景与背景装饰
  • 市政工程保温胶水哪家效果好? - 中媒介
  • SpringBoot集成Activiti/Flowable工作流引擎与bpmnjs流程设计器实战
  • LangChain 之 【RAG简介、文档加载器、文本分割器】
  • 贵阳贵安数字应用场景案例解析与关键技术
  • 四川能做照片定制的蛋糕店 - 中媒介