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

HarmonyOS掌上记账APP开发实践第94篇:如何实现删除多选框选项功能

如何删除多选框选项

场景说明

通常情况下,我们使用多选框都会伴随对选项的操作,比较常见的操作是选中后删除,比如删除购物车的商品、删除账单、删除图片等等。但是,当前HarmonyOS针对多选框组件并没有提供直接的删除其选项的方法,需要开发者自己来实现。本例提供了一种实现方案,供开发者参考。

效果呈现

本例demo最终效果如下:

实现思路

本例中涉及的关键特性及实现方案如下:

  • 多选框:使用CheckboxGroup组件构建多选框标题,使用Checkbox组件构建多选框选项。
  • 删除多选框选项:通过CheckboxGroup的onChange回调获取到各个选项的选中状态,在删除操作中,将选中的选项从选项列表中删除。
  • 删除时弹出确认框:使用promptAction模块调用showDialog方法弹出对话框,通过回调获取到用户点击的是取消按钮还是确定按钮,如果是确定按钮则执行删除操作。

开发步骤

  1. 搭建UI布局。
    整体纵向布局,那就采用Column组件;全选框用CheckboxGroup组件,然后每个选项都包括一个选择框(Checkbox组件)和一个文本(Text组件),且为横向布局,那我们可以把它们放在Flex组件中;最后是一个Button组件。这样整体布局就有了,具体代码如下:

    @Componentstruct CheckboxDemo{build(){Column(){Flex({}){CheckboxGroup({})Text('水果清单')}Flex({}){Checkbox({})Text('苹果')}Flex({}){Checkbox({})Text('菠萝')}Flex({}){Checkbox({})Text('柚子')}Button('删除')}}}

    框架搭好了,看下效果:

    可以看到主选框和选项对齐了,接下来我们来调整下样式。
    先给CheckboxGroup取个名字:fruit_list,然后为各个Checkbox添加相同的group名称,这样就可以将Checkbox挂靠到CheckboxGroup下,剩下的就是给各个组件添加margin、fontSize等通用属性了,不清楚各个组件有哪些属性的请自行查阅组件参考,具体代码如下:

    @Componentstruct CheckboxDemo{build(){Column(){Flex({justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){// 将CheckboxGroup命名为'fruit_list'CheckboxGroup({group:'fruit_list'}).selectedColor('#007DFF')Text('水果清单').margin({right:20}).fontSize(14).lineHeight(20).fontColor('#182431').fontWeight(FontWeight.Bold)}Flex({justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){// 通过group参数将Checkbox挂到CheckboxGroup下Checkbox({name:'苹果',group:'fruit_list'}).selectedColor('#007DFF')Text('苹果').margin({right:20}).fontSize(14).lineHeight(20).fontColor('#182431').fontWeight(500)}Flex({justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){Checkbox({name:'菠萝',group:'fruit_list'}).selectedColor('#007DFF')Text('菠萝').margin({right:20}).fontSize(14).lineHeight(20).fontColor('#182431').fontWeight(500)}Flex({justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){Checkbox({name:'柚子',group:'fruit_list'}).selectedColor('#007DFF')Text('柚子').margin({right:20}).fontSize(14).lineHeight(20).fontColor('#182431').fontWeight(500)}Button('删除').margin({top:20,left:35}).fontSize(15).padding({top:5,bottom:5,left:15,right:15})}}}

    我们再来看下效果,发现多选框的布局已经正常了:

  2. 简化代码。
    当前代码重复性很高,包含Checkbox的三个Flex的结构完全一样,我们可以简化一下。把重复的结构通过@Builder抽取出来作为一个自定义组件,用到的地方进行引用即可;每个Flex呈现的内容不同,那就将不同的内容作为参数传入。具体代码如下:

    @Componentstruct CheckboxDemo{// flexNameList存储checkbox选项的文本内容;使用@State修饰后,flexNameList发生变化,UI会同步刷新@StateflexNameList:string[]=['苹果','菠萝','柚子']@Builder// 将重复内容封装成flexItem,通过参数checkboxName为Text组件传入显示文本,通过groupName绑定CheckboxGroupflexItem(checkboxName:string,groupName:string){Flex({justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){Checkbox({name:checkboxName,group:groupName}).selectedColor('#007DFF')Text(checkboxName).margin({right:20}).fontSize(14).lineHeight(20).fontColor('#182431').fontWeight(500)}.margin({left:36})}build(){Column(){Flex({justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){CheckboxGroup({group:'fruit_list'}).selectedColor('#007DFF')Text('水果清单').margin({right:20}).fontSize(14).lineHeight(20).fontColor('#182431').fontWeight(FontWeight.Bold)}// 通过ForEach遍历flexNameList循环渲染生成UIForEach(this.flexNameList,(item:any)=>{// 引用封装的flexItem模板this.flexItem(item,'fruit_list')})Button('删除').margin({top:20,left:35}).fontSize(15).padding({top:5,bottom:5,left:15,right:15})}.alignItems(HorizontalAlign.Center)}}
  3. 添加删除逻辑。
    本例中是通过以下方式实现删除操作的:将选中的水果项从flexNameList中删除(为方便展示,本文直接将数据存储在数组中,实际开发需要对接数据库),由于flexNameList被@State修饰,所以其发生变化时会重新执行Build(),从而完成UI刷新,展示删除后的选项。
    要实现上述逻辑,首先需要获取到被选中的水果项。这里可以通过CheckboxGroup的onChange回调获取,当选项的状态发生变化时,会触发回调并返回各选项的选中状态。
    具体代码如下:

    @Componentstruct CheckboxDemo{...// itemStatus用来存储各选项的选中状态privateitemStatus:CheckboxGroupResult...build(){Column(){Flex({justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){CheckboxGroup({group:'fruit_list'}).selectedColor('#007DFF')// 选项状态发生变化时触发onChange回调,各选项的选中状态储存在itemName中并返回,通过itemStatus.name可以获取到被选中的选项列表.onChange((itemName:CheckboxGroupResult)=>{this.itemStatus=itemName})...}.alignItems(HorizontalAlign.Center)}}

    将各选项的选中状态存储到itemStatus后,我们就可以通过Button触发删除操作了。当点击删除按钮时,触发删除操作,所以给Button添加onClick事件,并添加删除逻辑。代码如下:

    @Componentstruct CheckboxDemo{......// itemStatus用来存储各选项的选中状态privateitemStatus:CheckboxGroupResult......build(){Column(){Flex({justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){CheckboxGroup({group:'fruit_list'}).selectedColor('#007DFF')// 选项状态发生变化时触发onChange回调,各选项的选中状态储存在itemName中并返回,通过itemStatus.name可以获取到被选中的选项列表.onChange((itemName:CheckboxGroupResult)=>{this.itemStatus=itemName})......Button('删除').margin({top:20,left:35}).fontSize(15).padding({top:5,bottom:5,left:15,right:15})// 点击触发删除操作.onClick(()=>{// 被选中的项存储在this.itemStatus.name列表中for(letiofthis.itemStatus.name){// 从flexNameList中删除被选中的项,刷新UIthis.flexNameList.splice(this.flexNameList.indexOf(i),1)}})}.alignItems(HorizontalAlign.Center)}}
  4. 添加删除确认框。
    使用promptAction模块调用showDialog方法弹出对话框,然后将删除操作绑定到对话框的确定按钮,具体代码如下:

    // 导入promptAction模块importpromptActionfrom'@ohos.promptAction';@Componentstruct CheckboxDemo{......// itemStatus用来存储各选项的选中状态privateitemStatus:CheckboxGroupResult......build(){Column(){Flex({justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){CheckboxGroup({group:'fruit_list'}).selectedColor('#007DFF')// 选项状态发生变化时触发onChange回调,各选项的选中状态储存在itemName中并返回,通过itemStatus.name可以获取到被选中的选项列表.onChange((itemName:CheckboxGroupResult)=>{this.itemStatus=itemName})......Button('删除').margin({top:20,left:35}).fontSize(15).padding({top:5,bottom:5,left:15,right:15})// 点击触发删除操作.onClick(()=>{// 调用对话框promptAction.showDialog({title:'',message:'确定删除吗?',buttons:[{text:'取消',color:'#000000'},{text:'确定',color:'#000000'}]})// 用户选择通过data回传,当data.index为1时,用户选择确定,当data.index为0时,用户选择取消.then(data=>{// 当用户选择确定时,进行删除操作if(data.index===1){// 被选中的项存储在this.itemStatus.name列表中for(letiofthis.itemStatus.name){// 从flexNameList中删除被选中的项,刷新UIthis.flexNameList.splice(this.flexNameList.indexOf(i),1)}}})})}.alignItems(HorizontalAlign.Center)}}

完整代码

本例完整代码如下:

importpromptActionfrom'@ohos.promptAction';@Entry@Componentstruct CheckboxDemo{@StateflexNameList:string[]=['苹果','菠萝','柚子']privateitemStatus:CheckboxGroupResult@BuilderflexItem(checkboxName:string,groupName:string){Flex({justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){Checkbox({name:checkboxName,group:groupName}).selectedColor('#007DFF')Text(checkboxName).margin({right:20}).fontSize(14).lineHeight(20).fontColor('#182431').fontWeight(500)}.margin({left:36})}build(){Column(){if(this.flexNameList.length!=0){Flex({justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center}){CheckboxGroup({group:'fruit_list'}).selectedColor('#007DFF').onChange((itemName:CheckboxGroupResult)=>{this.itemStatus=itemName})Text('水果清单').margin({right:20}).fontSize(14).lineHeight(20).fontColor('#182431').fontWeight(FontWeight.Bold)}.margin({top:150})ForEach(this.flexNameList,(item:any)=>{this.flexItem(item,'fruit_list')})Button("删除").margin({top:20,left:35}).fontSize(15).padding({top:5,bottom:5,left:15,right:15}).onClick(()=>{promptAction.showDialog({title:'',message:'确定删除吗?',buttons:[{text:'取消',color:'#000000'},{text:'确定',color:'#000000'}]}).then(data=>{if(data.index===1){for(letiofthis.itemStatus.name){this.flexNameList.splice(this.flexNameList.indexOf(i),1)}}})})}else{}}.alignItems(HorizontalAlign.Center)}}

参考

  • ChecckboxGroup
  • Checkbox
  • Flex
  • Button
  • ohos.promptAction (弹窗)
  • ForEach循环渲染
  • @State状态管理
  • @Builder动态构建UI元素
http://www.jsqmd.com/news/1294311/

相关文章:

  • C++与OpenCV实现传统美颜算法:瘦脸、大眼与磨皮技术详解
  • A-59U双通道语音模块:USB免驱架构下的通道隔离与波束性能边界
  • 量子隐形传态:从量子纠缠到量子互联网的核心技术解析
  • 2026年安徽合肥技师学院是公办还是民办?毕业证国家承认吗?咨询电话多少? - 最新资讯
  • Solarflare网卡与OpenOnload部署实战:从驱动安装到性能调优
  • C/C++实现XZ-Ordering空间索引:原理、位交织与高性能优化
  • 山东涡街流量计制造厂家哪些比较好?
  • 2026漠河报团避坑全攻略|5大雷区+5条筛选铁律,实测10家机构,普通人闭眼选不踩雷 - 互联网科技品牌测评
  • 二七区奥迪德系专修宝顺奥迪德系专修申师傅店:车主维保调研解析 - 百航
  • 爱情背后的科学机制:从多巴胺到催产素的神经生物学解析
  • 蒸汽教育如何处理长期服务中的信息断层?
  • PDF-Lib 3层架构设计:构建跨平台JavaScript PDF处理引擎的实现指南
  • PyWxDump:逆向解析微信本地数据库,实现数据自主备份与智能迁移
  • 深圳AI智能体培训机构推荐 - 专业课程与就业前景深度解析
  • 2026 蒙自品质装修口碑榜单|美颂装饰,17 年本土深耕凭个性化设计与管家式服务稳居优选 - 推途云
  • 4步轻松搞定微信防撤回:RevokeMsgPatcher完整使用指南
  • 紧急预警:头条已上线AI内容识别V2.3,未做这3项人工干预的账号本周起限流!
  • 论文科研绘图别硬画❌零基础也能出盲审级图表
  • 2026年瑞之幸商贸:实体商贸与数字化技术融合的典范
  • 2026红河州蒙自装修公司口碑排行|本地人真实测评!中高端整装,美颂装饰凭25年经验+个性化设计出圈 - 推途云
  • 节日走亲访友适合哪种礼盒有检测报告的羊奶粉 - 资讯在线
  • 【独家首发】2024中国AI仓储渗透率地图:TOP10城市部署热力图+中小企适配成本红线(数据源自372家实地调研)
  • 蒸汽求职为什么更需要讲清限制,而不是放大承诺?
  • 长沙黄金回收避坑指南!看懂四不五要,不被压价不踩雷 - 一日一测评
  • Parquet Viewer:浏览器端Parquet文件查看与SQL查询的终极解决方案
  • 测试平台与CI/CD集成:数据同步问题深度解析与实战修复方案
  • QGroundControl地面站终极指南:从零开始掌握无人机控制
  • 激光振镜矫正:从非线性误差到高精度加工的实现原理与ZMC420SCAN实践
  • Windows内存优化终极指南:让老旧电脑重获新生的免费神器
  • 2026年江阴市装修避坑与服务商甄别方法有哪些?艺上云间13961605791家装挑选参考指南 - GrowthUME