如何实现列表项的新增和删除—OpenHarmony

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

想了解更多关于开源的内容,请访问:

51CTO 开源基础软件社区

https://ost.51cto.com

场景介绍

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

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

环境要求

本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:

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

新增列表项

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

如何实现列表项的新增和删除(OpenHarmony)-开源基础软件社区

图17 新增待办

开发步骤

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

import util from '@ohos.util';

export class ToDo {
  key: string = util.generateRandomUUID(true);
  name: string;

  constructor(name: string) {
    this.name = name;
  }
}

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

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

构建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)
}

为新增按钮绑定点击事件,并在事件中通过TextPickerDialog.show添加新增列表项的逻辑:

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

删除列表项

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

如何实现列表项的新增和删除(OpenHarmony)-开源基础软件社区

图18 长按删除待办事项

开发步骤

列表的删除功能一般进入编辑模式后才可使用,所以需要提供编辑模式的入口。
以待办列表为例,通过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); // 记录长按时选中的列表项
      }
    })
  )
)

需要响应用户的选择交互,记录要删除的列表项数据。
在待办列表中,通过勾选框的勾选或取消勾选,响应用户勾选列表项变化,记录所有选择的列表项。

// 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中删除
        }
      }
    })
    ...
}

需要响应用户点击删除按钮事件,删除列表中对应的选项。

// ToDoList.ets

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

    this.toDoData = leftData;
    this.isEditMode = false;
  })
  ...

完整示例代码

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

待办事项数据结构代码(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;
  }
}

待办事项列表代码(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%')
  }
}

待办事项代码(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)
        }
      })
    )
    )
  }
}

想了解更多关于开源的内容,请访问:

51CTO 开源基础软件社区

https://ost.51cto.com

责任编辑:jianghua 来源: 51CTO 开源基础软件社区
相关推荐

2023-08-24 16:42:29

Sample聊天实例应用

2024-01-10 17:27:00

Python开发

2024-04-30 11:02:15

二级联动鸿蒙开源

2022-03-14 10:02:03

散列表链表哈希表

2022-03-24 14:58:02

Java散列表编程语言

2022-05-31 15:27:11

CSS动画

2022-11-11 07:48:56

ORM链式轮播图

2022-11-15 07:50:47

ORM链式操作删除

2010-07-07 16:53:54

SQL Server重

2017-03-13 10:11:28

AndroidRecyclerVie功能介绍

2024-04-01 09:42:16

2010-09-01 16:43:26

Squid ACLSquid访问列表Squid

2009-06-11 10:35:49

图像下拉列表imgdiv

2023-06-05 15:00:13

书籍翻页动效鸿蒙

2023-07-17 16:13:21

组件模块开发的鸿蒙

2010-10-22 17:33:02

2023-02-13 15:59:17

鸿蒙Beta5源码

2010-11-23 14:40:04

MySQL多表删除

2010-10-15 15:02:37

Mysql多表删除
点赞
收藏

51CTO技术栈公众号