鸿蒙应用开发实战【95】— 实战应用状态批量管理操作
本文是「号码助手全栈开发系列」第 95 篇,持续更新中…
开源社区:https://openharmonycrossplatform.csdn.net
前言
批量操作是提升用户效率的关键功能。号码助手的首页支持多选模式,用户可一次性对多个应用进行状态变更(换绑 / 注销)或删除。本篇讲解选择模式状态管理、批量操作栏 UI 和 DAO 层的批量操作实现。
本篇涵盖:选择模式(selectMode)状态机、Swipe 手势切换、批量操作栏(BulkActionBar)、选中 IDs 管理、批量状态更新
batchUpdateStatus、批量删除deleteMany。
一、选择模式状态机
文件:pages/HomePage.ets
@StateselectMode:boolean=false// 是否处于选择模式@StateselectedIds:number[]=[]// 选中的应用绑定 id 列表状态转换:
普通模式 ──长按应用列表──→ 选择模式 选择模式 ──点击"取消"──→ 普通模式 选择模式 ──执行批量操作──→ 普通模式 选择模式 ──选中 0 项──→ 普通模式(自动退出)二、进入选择模式
2.1 长按触发
// AppListItem 组件中@BuilderAppListItem(item:AppRow){Column().gesture(LongPressGesture({duration:500}).onAction(()=>{this.enterSelectMode()this.toggleSelection(item.binding.id!)}))}2.2 切换选中状态
privatetoggleSelection(id:number):void{constidx=this.selectedIds.indexOf(id)if(idx>=0){this.selectedIds.splice(idx,1)}else{this.selectedIds.push(id)}// 选中状态变更数组引用(触发 @State 更新)this.selectedIds=[...this.selectedIds]// 如果取消选中最后一个,自动退出选择模式if(this.selectedIds.length===0){this.selectMode=false}}三、批量操作栏(BulkActionBar)
进入选择模式后,底部出现批量操作栏:
┌─────────────────────────────────────────┐ │ 已选中 3 项 换绑 注销 删除 │ └─────────────────────────────────────────┘// 选择模式时的底部操作栏if(this.selectMode){Row(){Text(`已选中${this.selectedIds.length}项`).fontSize(AppFonts.BODY).fontColor(AppColors.TEXT_2).layoutWeight(1)Text('换绑').onClick(()=>this.batchRebind())Text('注销').onClick(()=>this.batchCancel())Text('删除').fontColor(AppColors.DANGER).onClick(()=>this.batchDelete())}.width('100%').height(56).padding({left:16,right:16}).backgroundColor(AppColors.CARD_B).border({width:{top:1},color:AppColors.LINE})}四、DAO 层批量操作
4.1 批量更新状态
文件:features/data/AppBindingDao.ets
/** * 批量更新应用绑定状态 * @param ids 要更新的记录 id 列表 * @param newStatus 目标状态 */staticasyncbatchUpdateStatus(ids:number[],newStatus:BindingStatus):Promise<number>{try{conststore=AppBindingDao.getStore()constpredicates=newrelationalStore.RdbPredicates(TABLE)predicates.in('id',ids.map(String))// IN 查询constvalues:relationalStore.ValuesBucket={status:newStatus,updated_at:Date.now()}constaffectedRows=awaitstore.update(values,predicates)hilog.info(0x0000,TAG,'batchUpdateStatus: %{public}d 行受影响',affectedRows)returnaffectedRows}catch(e){hilog.error(0x0000,TAG,'batchUpdateStatus 失败: %{public}s',JSON.stringify(e))thrownewError('batchUpdateStatus 失败: '+JSON.stringify(e))}}4.2 批量删除
/** * 批量删除应用绑定 * @param ids 要删除的记录 id 列表 */staticasyncdeleteMany(ids:number[]):Promise<number>{try{conststore=AppBindingDao.getStore()constpredicates=newrelationalStore.RdbPredicates(TABLE)predicates.in('id',ids.map(String))constaffectedRows=awaitstore.delete(predicates)hilog.info(0x0000,TAG,'deleteMany: %{public}d 行删除',affectedRows)returnaffectedRows}catch(e){hilog.error(0x0000,TAG,'deleteMany 失败: %{public}s',JSON.stringify(e))thrownewError('deleteMany 失败: '+JSON.stringify(e))}}五、批量换绑完整流程
privateasyncbatchRebind():Promise<void>{if(this.selectedIds.length===0)returntry{// 1. 将所有选中项改为"待换绑"awaitAppBindingDao.batchUpdateStatus(this.selectedIds,'待换绑')// 2. 刷新首页数据awaitthis.loadData()// 3. 退出选择模式this.selectMode=falsethis.selectedIds=[]promptAction.showToast({message:`已将${ids.length}项标记为待换绑`})}catch(e){hilog.error(0x0000,TAG,'batchRebind failed: %{public}s',JSON.stringify(e))promptAction.showToast({message:'批量操作失败,请重试'})}}六、关键 predicates API
批量操作依赖RdbPredicates.in()实现:
// predicates 链式调用constpredicates=newrelationalStore.RdbPredicates('app_bindings')predicates.in('id',['1','2','3'])// WHERE id IN (1,2,3)// 生成的 SQL// UPDATE app_bindings SET status = ?, updated_at = ? WHERE id IN (1,2,3)// DELETE FROM app_bindings WHERE id IN (1,2,3)七、UI 层级结构
HomePage ├── 标题栏(selectMode 为 true 时显示"取消"按钮) ├── 统计卡片(选择模式下半透明) ├── 应用列表(带选中态勾选标记) │ └── ForEach → AppListItem │ ├── 普通模式:显示状态标签 │ └── 选择模式:显示勾选框 ├── 三维筛选面板(选择模式下隐藏) └── 批量操作栏(仅选择模式下显示)选中态 UI 实现:
// AppListItem 选中样式Column().opacity(rowSelected?0.7:1)// 选中项半透明.border({width:rowSelected?1:0,color:AppColors.PRIMARY,radius:14})八、Swipe 手势切换选择模式
除了长按,还可以通过横向滑动切换选择模式:
// SwipeGesture 手势Column().gesture(SwipeGesture({direction:SwipeDirection.Left}).onAction((event:GestureEvent)=>{if(event.offsetX<-50){// 左滑超过 50pxthis.enterSelectMode()}}))小结
| 功能 | 实现 | 关键代码 | 适用场景 |
|---|---|---|---|
| 选择模式 | @State selectMode + toggleSelection | 长按触发 | 批量管理 |
| 选中管理 | selectedIds 数组 + 引用替换触发刷新 | [...this.selectedIds] | 选中计数的 State 更新 |
| 批量更新状态 | AppBindingDao.batchUpdateStatus() | predicates.in() | 标记换绑/注销 |
| 批量删除 | AppBindingDao.deleteMany() | predicates.in() | 删除无用绑定 |
| 操作栏 | 条件渲染if (this.selectMode) | 换绑/注销/删除三个按钮 | 底部操作栏 |
| 手势 | LongPressGesture 500ms | 长按进入 / 左滑进入 | 触发选择模式 |
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
- HarmonyOS relationalStore API:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/relationalstore
- HarmonyOS 官方文档:https://developer.huawei.com/consumer/cn/doc/
- HarmonyOS hilog文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/hilog
- HarmonyOS testing:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/unit-test
- HarmonyOS 安全与权限:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/permissions-overview