HarmonyOS7 LongPressGesture 做编辑模式:长按只负责开门
2026/7/24 21:29:04 网站建设 项目流程

文章目录

      • 前言
      • 为什么这个问题经常被写乱
      • 先把模式讲清楚
      • 先把页面目标想清楚
      • 完整 ArkTS 示例
      • 把关键代码一段段拆开
      • 交互细节
      • 新手最容易踩的坑
      • 放进真实项目还要补什么
      • 写在最后

前言

长按进入编辑模式很常见,桌面图标、图片列表、频道管理都能用到。但这里最容易写乱的不是LongPressGesture,而是进入编辑模式以后:点击到底是打开,还是选中?再次长按要不要重复切换?完成后选中状态要不要清空?

我的做法很简单:长按只负责进入编辑模式,后面的选择、取消、完成都交给明确状态。不要让一个手势同时承担入口、选择和提交。

为什么这个问题经常被写乱

LongPressGesture 做编辑模式 这类内容很容易被写成“代码能跑就算讲完了”,但对初学者来说,这恰恰是最不够的地方。真正让人卡住的,往往不是某个组件名记不住,而是不知道这段代码为什么要这样拆、状态为什么要这样放、以后需求变化时应该从哪里改。

所以这篇文章不只想给你一个能跑的例子,更想把背后的判断过程讲清楚。你只要把这个判断过程吃透,后面自己改页面、补需求、查问题时,心里会稳很多。

先把模式讲清楚

普通模式和编辑模式的点击行为完全不同,代码里要先承认这件事。

模式点击图标长按图标页面表现
普通模式打开应用或详情进入编辑并选中当前项不显示角标
编辑模式选中或取消选中保持编辑模式显示选择角标和完成按钮

这样拆开后,editing只表示页面模式,selectedIds只表示已选中的数据,互相不抢职责。

先把页面目标想清楚

在真正写代码之前,先别急着盯着 API。更有用的做法是先想清楚:这个页面到底想解决什么问题,用户最在意的反馈是什么,哪些状态必须一直保持一致。

当你先把这条主线想明白,再回头看组件和状态设计,很多选择都会顺理成章。对小白来说,这一步尤其重要,因为它能帮你从“照着抄”慢慢过渡到“看得懂、改得动”。

完整 ArkTS 示例

interfaceDesktopAppItem{id:numbername:stringcolor:string}@Entry@Componentstruct LongPressEditPage{@Stateediting:boolean=false@StateselectedIds:number[]=[]privateapps:DesktopAppItem[]=[{id:1,name:'日程',color:'#1E88E5'},{id:2,name:'笔记',color:'#43A047'},{id:3,name:'文件',color:'#FB8C00'},{id:4,name:'设置',color:'#5E35B1'}]privatetoggleSelect(id:number):void{if(this.selectedIds.includes(id)){this.selectedIds=this.selectedIds.filter((item:number)=>item!==id)return}this.selectedIds=this.selectedIds.concat([id])}privateenterEditing(id:number):void{this.editing=trueif(!this.selectedIds.includes(id)){this.selectedIds=this.selectedIds.concat([id])}}privatefinishEditing():void{this.editing=falsethis.selectedIds=[]}build(){Column({space:14}){Row(){Text(this.editing?`已选${this.selectedIds.length}`:'我的桌面').fontSize(22).fontWeight(FontWeight.Bold)Blank()if(this.editing){Button('完成').height(34).onClick(()=>this.finishEditing())}}.width('100%')Grid(){ForEach(this.apps,(item:DesktopAppItem)=>{GridItem(){Stack({alignContent:Alignment.TopEnd}){Column({space:8}){Text(item.name.substring(0,1)).fontSize(20).fontColor(Color.White).width(54).height(54).textAlign(TextAlign.Center).backgroundColor(item.color).borderRadius(14)Text(item.name).fontSize(13)}.justifyContent(FlexAlign.Center).width('100%').height('100%')if(this.editing){Text(this.selectedIds.includes(item.id)?'✓':'').width(22).height(22).fontSize(14).fontColor(Color.White).textAlign(TextAlign.Center).backgroundColor(this.selectedIds.includes(item.id)?'#1E88E5':'#DDDDDD').borderRadius(11)}}}.height(96).onClick(()=>{if(this.editing){this.toggleSelect(item.id)}}).gesture(LongPressGesture().onAction(()=>this.enterEditing(item.id)))},(item:DesktopAppItem)=>item.id.toString())}.columnsTemplate('1fr 1fr 1fr 1fr').rowsGap(12).columnsGap(8)}.padding(16)}}

把关键代码一段段拆开

editing是模式开关。标题、完成按钮、选择角标都依赖它,这样用户不会只凭一次长按反馈来猜当前状态。

selectedIds只存 id,不存整条对象。编辑模式常见后续动作是批量删除、批量移动、提交给接口,用 id 会更轻,也更不容易遇到对象引用变化的问题。

enterEditing()负责长按入口,并自动选中当前项。这符合用户直觉:我长按了某个图标,进入编辑后它应该已经被选中。

普通模式下的点击示例里没有写跳转逻辑,是为了突出编辑模式本身。真实项目里可以在!this.editing时执行打开详情或启动应用。

交互细节

完成按钮要清理selectedIds。如果只把editing改成false,下次再进入编辑模式时可能保留旧选择,用户会觉得页面状态串了。

长按不要反复把模式开关取反。用户在编辑模式里再次长按某个图标,通常不希望退出编辑,而是继续保持当前模式。

新手最容易踩的坑

这一类示例最容易让人产生错觉:界面出来了,就以为已经掌握了。其实真正容易出问题的地方,通常都在效果之外,比如状态有没有收拢、失败后怎么兜底、以后要扩展时会不会牵一发动全身。

所以你练这篇内容时,别只看“现在能不能跑”,还要继续看“以后好不好改”。能把这个习惯养起来,你写出来的页面会比单纯照着示例拼出来的页面稳很多。

放进真实项目还要补什么

示例代码的重点是把核心思路讲明白,所以很多工程化细节会故意省掉。真正落到项目里时,你通常还要继续补接口联动、异常处理、边界保护、资源抽离,以及和其他页面状态之间的配合。

比较稳的做法是分三步走:先把结构和职责立住,再把真实业务接进去,最后再优化视觉和交互体验。这样改出来的页面不只是“能演示”,而是真的更接近可以长期维护的业务代码。

写在最后

LongPressGesture只是编辑模式的入口,真正的体验来自模式状态和选择状态。把这两个状态拆开,页面就不容易出现误触、残留选择和行为不一致。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询