OpenHarmony开发实战:ArkUI案例-列表项的新增和删除规范

137 篇文章 0 订阅
133 篇文章 0 订阅

场景

列表的编辑模式用途十分广泛,常见于待办事项管理、文件管理、备忘录的记录管理等应用场景。在列表的编辑模式下,新增和删除列表项是最基础的功能,其核心是对列表项对应的数据集合进行数据添加和删除。

下面以待办事项管理为例,介绍如何快速实现新增和删除列表项功能。

环境要求

  • IDE:DevEco Studio 3.1 Beta1
  • SDK:Ohos_sdk_public 3.2.11.9 (API Version 9 Release)

新增列表项

如下图所示,当用户点击添加按钮时,将弹出列表项选择界面,用户点击确定后,列表中新增对应项目。

图17 新增待办  

新增列表

开发步骤

  1. 定义列表项数据结构和初始化列表数据,构建列表整体布局和列表项。 以待办事项管理为例,首先定义待办事项的数据结构:

    import util from '@ohos.util';
    
    export class ToDo {
      key: string = util.generateRandomUUID(true);
      name: string;
    
      constructor(name: string) {
        this.name = name;
      }
    }

  2. 然后,初始化待办事项列表和可选事项列表:

    @State toDoData: ToDo[] = [];
    private availableThings: string[] = ['读书', '运动', '旅游', '听音乐', '看电影', '唱歌'];

  3. 构建UI界面。 初始界面包含“待办”和新增按钮“+”:

    Text('待办')
      .fontSize(36)
      .margin({ left: 40})
    Blank()
    Text('+')
      .fontWeight(FontWeight.Lighter)
      .fontSize(40)
      .margin({ right: 30 })

    构建列表布局并通过ForEach循环渲染列表项:

    List({ space: 10 }) {
      ForEach(this.toDoData, (toDoItem) => {
        ListItem() {
          ...
        }
      }, toDoItem => toDoItem.key)
    }
  4. 为新增按钮绑定点击事件,并在事件中通过TextPickerDialog.show添加新增列表项的逻辑:

    Text('+')
      .onClick(() => {
        TextPickerDialog.show({
          range: this.availableThings, // 将可选事项列表配置到选择对话框中
          onAccept: (value: TextPickerResult) => {
             this.toDoData.push(new ToDo(this.availableThings[value.index])); // 用户点击确认,将选择的数据添加到待办列表toDoData中
          },
        })
      })

删除列表项

如下图所示,当用户长按列表项进入删除模式时,提供用户删除列表项选择的交互界面,用户勾选完成后点击删除按钮,列表中删除对应的项目。

图18 长按删除待办事项

删除列表

开发步骤

  1. 列表的删除功能一般进入编辑模式后才可使用,所以需要提供编辑模式的入口。 以待办列表为例,通过LongPressGesture()监听列表项的长按事件,当用户长按列表项时,进入编辑模式。

    // ToDoListItem.ets
    
    Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
      ...
    }
    .gesture(
    GestureGroup(GestureMode.Exclusive,
      LongPressGesture() // 监听长按事件
        .onAction(() => {
          if (!this.isEditMode) {
            this.isEditMode = true; //进入编辑模式
            this.selectedItems.push(this.toDoItem); // 记录长按时选中的列表项
          }
        })
      )
    )
  2. 需要响应用户的选择交互,记录要删除的列表项数据。 在待办列表中,通过勾选框的勾选或取消勾选,响应用户勾选列表项变化,记录所有选择的列表项。

    // ToDoListItem.ets
    
    if (this.isEditMode) {
      Checkbox()
        .onChange((isSelected) => {
          if (isSelected) {
            this.selectedItems.push(this.toDoItem) // 勾选时,记录选中的列表项
          } else {
            let index = this.selectedItems.indexOf(this.toDoItem)
            if (index !== -1) {
              this.selectedItems.splice(index, 1) // 取消勾选时,则将此项从selectedItems中删除
            }
          }
        })
        ...
    }
  3. 需要响应用户点击删除按钮事件,删除列表中对应的选项。

    // ToDoList.ets
    
    Button('删除')
      .onClick(() => {
        // 删除选中的列表项对应的toDoData数据
        let leftData = this.toDoData.filter((item) => {
          return this.selectedItems.find((selectedItem) => selectedItem !== item);
        })
    
        this.toDoData = leftData;
        this.isEditMode = false;
      })
      ...

完整示例代码

新增和删除列表项的实现共涉及三个文件,各文件完整代码如下:

  1. 待办事项数据结构代码(ToDo.ets):
    // ToDo.ets
    import util from '@ohos.util';
    
    export class ToDo {
      key: string = util.generateRandomUUID(true)
      name: string;
    
      constructor(name: string) {
        this.name = name;
      }
    }
  2. 待办事项列表代码(ToDoList.ets):
    // ToDoList.ets
    import { ToDo } from '../model/ToDo';
    import { ToDoListItem } from './ToDoListItem';
    
    @Entry
    @Component
    struct ToDoList {
      @State toDoData: ToDo[] = []
      @Watch('onEditModeChange') @State isEditMode: boolean = false
      @State selectedItems: ToDo[] = []
    
      private availableThings: string[] = ["读书", "运动", "旅游", '听音乐', '看电影', '唱歌']
    
      saveData(value: string) {
        this.toDoData.push(new ToDo(value))
      }
    
      onEditModeChange() {
        if (!this.isEditMode) {
          this.selectedItems = []
        }
      }
    
      build() {
        Column() {
            Row() {
              if (this.isEditMode) {
                Text('X')
                  .fontSize(20)
                  .onClick(() => {
                    this.isEditMode = false;
                  })
                  .margin({ left: 20, right: 20 })
    
                Text('已选择' + this.selectedItems.length + '项')
                  .fontSize(24)
              } else {
                Text('待办')
                  .fontSize(36)
                  .margin({ left: 40})
                Blank()
                Text('+')
                  .fontWeight(FontWeight.Lighter)
                  .fontSize(40)
                  .margin({ right: 30 })
                  .onClick(() => {
                    TextPickerDialog.show({
                      range: this.availableThings,
                      onAccept: (value: TextPickerResult) => {
                        this.toDoData.push(new ToDo(this.availableThings[value.index]))
                        console.info('to do data: ' + JSON.stringify(this.toDoData))
                      },
                    })
                  })
              }
            }
            .height('12%')
            .width('100%')
    
            List({ initialIndex: 0, space: 10 }) {
              ForEach(this.toDoData, toDoItem => {
                ListItem() {
                    ToDoListItem({
                      isEditMode: $isEditMode,
                      toDoItem: toDoItem,
                      selectedItems: $selectedItems
                    })
                }.padding({ left: 24, right: 24, bottom: 12 })
              }, toDoItem => toDoItem.key)
            }
            .height('73%')
            .listDirection(Axis.Vertical)
            .edgeEffect(EdgeEffect.Spring)
    
          if (this.isEditMode) {
            Row() {
              Button('删除')
                .width('80%')
                .onClick(() => {
                  let leftData = this.toDoData.filter((item) => {
                    return this.selectedItems.find((selectedItem) => selectedItem != item)
                  })
                  console.log('leftData: ' + leftData);
                  this.isEditMode = false;
                  this.toDoData = leftData;
                })
                .backgroundColor('#ffd75d5d')
            }
            .height('15%')
          }
        }
        .backgroundColor('#fff1f3f5')
        .width('100%')
        .height('100%')
      }
    }
  3. 待办事项代码(ToDoListItem.ets):
    // ToDoListItem.ets
    import { ToDo } from '../model/ToDo';
    
    @Component
    export struct ToDoListItem {
      @Link isEditMode: boolean
      @Link selectedItems: ToDo[]
      private toDoItem: ToDo;
    
      hasBeenSelected(): boolean {
        return this.selectedItems.indexOf(this.toDoItem) != -1
      }
    
      build() {
        Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
          Row({ space: 4 }) {
            Circle()
              .width(24)
              .height(24)
              .fill(Color.White)
              .borderWidth(3)
              .borderRadius(30)
              .borderColor('#ffdcdfdf')
              .margin({ right: 10 })
    
            Text(`${this.toDoItem.name}`)
              .maxLines(1)
              .fontSize(24)
              .textOverflow({ overflow: TextOverflow.Ellipsis })
          }
          .padding({ left: 12 })
    
          if (this.isEditMode) {
            Checkbox()
              .select(this.hasBeenSelected() ? true : false)
              .onChange((isSelected) => {
                if (isSelected) {
                  this.selectedItems.push(this.toDoItem)
                } else {
                  let index = this.selectedItems.indexOf(this.toDoItem)
                  if (index != -1) {
                    this.selectedItems.splice(index, 1)
                  }
                }
              })
              .width(24)
              .height(24)
          }
        }
        .width('100%')
        .height(80)
        .padding({
          left: 16,
          right: 12,
          top: 4,
          bottom: 4
        })
        .borderRadius(24)
        .linearGradient({
          direction: GradientDirection.Right,
          colors: this.hasBeenSelected() ? [[0xffcdae, 0.0], [0xFfece2, 1.0]] : [[0xffffff, 0.0], [0xffffff, 1.0]]
        })
        .gesture(
        GestureGroup(GestureMode.Exclusive,
        LongPressGesture()
          .onAction(() => {
            if (!this.isEditMode) {
              this.isEditMode = true
              this.selectedItems.push(this.toDoItem)
            }
          })
        )
        )
      }
    }

最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。 

点击领取→【纯血版鸿蒙全套最新学习资料】(安全链接,放心点击希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、(南向驱动、嵌入式等)鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。


 鸿蒙(HarmonyOS NEXT)最新学习路线

有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

HarmonyOS Next 最新全套视频教程

 《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

《鸿蒙开发基础》

  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开发
  • .……

《鸿蒙开发进阶》

  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开发
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 任务管理
  • WebGL
  • 国际化开发
  • 应用测试
  • DFX面向未来设计
  • 鸿蒙系统移植和裁剪定制
  • ……

《鸿蒙进阶实战》

  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

大厂面试必问面试题

鸿蒙南向开发技术

鸿蒙APP开发必备

鸿蒙生态应用开发白皮书V2.0PDF


请点击→纯血版全套鸿蒙HarmonyOS学习资料

总结
总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,才能在这个变革的时代中立于不败之地。 

                   

  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值