Bootstrap

arkUI:水果选择与管理:基于 ArkUI 的长按编辑功能实现

1 主要内容说明

本文的代码主要用于对水果的管理应用,包含水果的添加、展示、选择、编辑和删除功能。用户可以从预置的水果列表中选择水果并动态显示在界面上,通过长按进入编辑模式后,可多选水果并批量删除。

主要功能包括:

  • 水果管理:通过弹窗选择水果,添加到展示列表中,防止重复选择。
  • 列表显示:水果项动态展示,序号和名称清晰,并支持通过背景颜色高亮已选中项。
  • 编辑模式:长按水果项进入编辑模式,显示复选框,用户可多选需要删除的水果。
  • 删除功能:选中水果后点击删除按钮,将选中的水果从列表中移除,同时退出编辑模式。

技术上,代码利用 @State 管理状态,通过事件绑定和条件渲染实现动态交互。视觉效果上使用渐变背景和排版细节提升用户体验。整体设计模块化,功能清晰,适合扩展到商品管理、任务列表等场景。

2 相关内容

2.1 相关内容

2.1.1 源码1内容的相关说明

2.1.1.1 数据结构与状态管理
  • 水果结构(fruit_mes)
    定义了一个接口 fruit_mes,用于描述水果项的结构,包含以下属性:
    -------------- id: 水果的唯一标识,用于区分不同的水果项。
    -------------- name: 水果的名称,用于显示。
  • 状态变量
    使用 @State 定义了多个变量,管理水果的增删改状态:
    -------------- message:一个字符串数组,包含预置的水果名称,供用户选择。
    -------------- message_toList:用户已选择的水果列表,类型为 fruit_mes[],用于动态展示。
    -------------- select_Item 和 select_Index:记录当前被选择的水果及其对应的索引,用于长按编辑模式。
    -------------- delete_Items 和 delete_Index:记录用户选中并打算删除的水果及其索引。
    -------------- isEdit:用于切换是否进入编辑模式。
    这些状态变量共同驱动 UI 的更新,用户的每一次操作都会实时反映在界面上。
2.1.1.2 添加水果功能
  • 通过 TextPickerDialog 弹出选择框,用户可以从预置水果列表中选择一个水果进行添加。逻辑如下:
    -------------- 弹出选择框,提供水果选项,用户确认后返回选中的水果索引和名称。
    -------------- 创建一个新的水果对象 { id, name }。
    -------------- 调用 have_Selected 方法,检查是否已添加过该水果:如果水果未被添加,则将其追加到 message_toList。如果已经存在,不进行任何操作,避免重复。
2.1.1.3 水果列表展示
  • 利用 List 和 ForEach 组件展示用户已选择的水果。核心特点包括:
    -------------- 序号与名称显示:水果项以“序号+名称”的形式呈现,序号从 1 开始。
    -------------- 动态背景颜色:未被选中的水果项使用默认渐变颜色。被选中的水果项(通过 item_has_been_selected 判断)显示特殊的高亮背景,提示当前状态。
    -------------- 布局样式:通过 Row 和 Text 配合 Blank,实现文本靠左,复选框靠右的排版。
2.1.1.4 长按进入编辑模式
  • 用户可以通过长按某个水果项,触发编辑模式,具体逻辑如下:
    -------------- 调用 LongPressGesture 的回调函数,将 isEdit 状态设置为 true。
    -------------- 将当前长按的水果项及其索引添加到 select_Item 和 select_Index。
    -------------- 更新 UI:显示复选框 Checkbox。显示“删除”按钮。
    -------------- 用户体验:长按操作是一个常见的交互习惯,特别适合列表编辑场景。
2.1.1.5 复选框的多选功能
  • 进入编辑模式后,每个水果项右侧会显示复选框,用户可以通过复选框选择多个水果。
    -------------- 使用 onChange 事件监听复选框状态的改变:当复选框被选中时,将对应水果和索引添加到 delete_Items 和 delete_Index。当复选框取消选中时,从上述数组中移除对应的数据。
    -------------- 动态更新数组,确保删除操作能够精确匹配用户选择。
2.1.1.6 删除水果功能
  • 用户完成多选后,可以点击“删除”按钮将选中的水果从列表中移除。
  • 删除逻辑:
    -------------- 遍历 delete_Index,依次从 message_toList 中删除对应的水果项。
    -------------- 清空 delete_Items 和 delete_Index,重置编辑状态。
    -------------- 退出编辑模式(isEdit = false),隐藏复选框和“删除”按钮。
2.1.1.7 样式与视觉效果
  • 使用渐变背景 (linearGradient) 为水果项提供动态的视觉提示:
    -------------- 默认状态下,使用冷色调渐变背景。
    -------------- 被选中的水果项使用暖色调渐变,突出显示。
  • 其他样式细节:
    -------------- 标题和按钮的字体大小、颜色和间距设计,提升整体美观性。
    -------------- 边距和圆角设计,让 UI 更加协调。

2.1.2 源码1 (水果选择与管理:基于 ArkUI 的长按编辑功能实现)

// 定义一个接口,用于表示水果的结构
interface fruit_mes {
  id: number; // 水果的唯一标识符
  name: string; // 水果的名称
}

@Entry
@Component
struct Case1114 {
  // 水果名称的数组(可供用户选择的水果列表)
  @State message: string[] = [
    "苹果1", "西瓜2", "猕猴桃3", "菠萝4", "葡萄5", "椰枣6", "哈密瓜7", "沙田柚8", "橙子9"
  ];

  // 用户已选择的水果项列表,存储为 `fruit_mes` 类型的数组
  @State message_toList: fruit_mes[] = [];

  // 是否处于编辑模式的标志位
  @State isEdit: boolean = false;

  // 长按选中的水果项列表,用于记录当前选中的水果项
  @State select_Item: fruit_mes[] = [];
  @State select_Index: number[] = []; // 长按选中的水果项对应的索引

  // 判断某水果项是否已被选中(长按选中状态)
  item_has_been_selected(item: fruit_mes): boolean {
    // 如果水果项已存在于 `select_Item` 中,返回 true,否则返回 false
    return this.select_Item.includes(item);
  }

  // 用户选中的待删除水果项列表
  @State delete_Items: fruit_mes[] = [];
  @State delete_Index: number[] = []; // 待删除水果项的索引列表

  // 判断某索引是否已被标记为删除
  index_has_been_delete(index: number): boolean {
    // 如果索引存在于 `select_Index` 中,返回 true,否则返回 false
    return this.select_Index.includes(index);
  }

  // 判断某水果项是否已添加到 `message_toList` 中
  have_Selected(item: fruit_mes): boolean {
    // 遍历已选水果列表,检查是否有相同的 id,若有返回 true
    return this.message_toList.some(fruit => fruit.id === item.id);
  }

  build() {
    Column() { // 整体页面布局为纵向排列
      // 顶部标题栏,显示标题和添加按钮
      Row() {
        // 显示标题文本
        Text("添加水果")
          .fontSize(40) // 字体大小
          .fontWeight(400) // 字体粗细
          .margin({ left: 10 }); // 左边距

        // 显示“+”按钮,用于打开选择对话框
        Text("+")
          .fontSize(40)
          .fontWeight(800) // 字体加粗
          .margin({ left: 10 }) // 左边距
          .fontColor("blue") // 按钮颜色为蓝色
          .onClick(() => {
            // 显示文本选择对话框,用户可以选择水果
            TextPickerDialog.show({
              range: this.message, // 提供的水果选项
              alignment: DialogAlignment.Center, // 对话框居中
              onAccept: (result: TextPickerResult) => {
                const index = result.index as number; // 用户选择的索引
                const name = result.value as string; // 用户选择的水果名称
                const newFruit: fruit_mes = { id: index, name: name }; // 创建新的水果项

                // 检查是否已添加,未添加则加入列表
                if (!this.have_Selected(newFruit)) {
                  this.message_toList.push(newFruit);
                  console.log(JSON.stringify(this.message_toList)); // 打印当前已选水果列表
                }
              }
            });
          });
      }
      .width("100%"); // 设置标题栏宽度为页面宽度

      // 分割线
      Divider()
        .color("red") // 红色分割线
        .height(20); // 高度为 20 vp

      // 使用 List 组件显示已选择的水果项
      List({ space: 5 }) { // 列表项之间的间距为 5
        ForEach(
          this.message_toList, // 遍历每个已选水果项
          (item: fruit_mes, index: number) => {
            ListItem() {
              Row() { // 每个列表项为一行
                // 显示水果的序号和名称
                Text(`${index + 1} --- ${item.name}`)
                  .fontSize(20) // 字体大小
                  .fontWeight(800) // 字体粗细
                  .fontColor("#ff0b4cc4"); // 字体颜色

                Blank(); // 空白占位符,保持复选框在右对齐

                // 如果索引被标记为删除,则显示复选框
                if (this.index_has_been_delete(index)) {
                  Checkbox()
                    .onChange((isChecked) => {
                      if (isChecked) {
                        // 若复选框选中,将该项添加到待删除数组
                        this.delete_Items.push(item);
                        this.delete_Index.push(index);
                      } else {
                        // 若取消选中,则从待删除数组移除
                        this.delete_Items = this.delete_Items.filter(f => f !== item);
                        this.delete_Index = this.delete_Index.filter(i => i !== index);
                      }
                    });
                }
              }
              .width("100%") // 每行宽度占满
              .height(50) // 每行高度为 50
              .borderRadius(20) // 设置圆角效果
              .padding({ left: 20, right: 20 }) // 左右内边距
              .linearGradient({
                direction: GradientDirection.RightTop, // 渐变方向
                // 根据是否选中决定渐变背景颜色
                colors: this.item_has_been_selected(item)
                  ? [["#ffe7b720", 0.4], ["#ffee205a", 1]] // 选中时颜色
                  : [["#ff35ace3", 0.4], ["#ff1ff834", 1]] // 未选中时颜色
              })
              .gesture(
                LongPressGesture().onAction(() => {
                  this.isEdit = true; // 激活编辑模式

                  // 长按后将选中项添加到选中数组
                  if (!this.select_Item.includes(item)) {
                    this.select_Item.push(item);
                    this.select_Index.push(index);
                  }

                  console.log(JSON.stringify(this.select_Item)); // 打印选中项
                  console.log(JSON.stringify(this.select_Index)); // 打印选中索引
                })
              );
            };
          }
        );
      }
      .width("100%") // 列表宽度占满
      .height("auto"); // 高度根据内容自动调整

      // 编辑模式下显示删除按钮
      if (this.isEdit) {
        Button("删除")
          .width("50%") // 按钮宽度为页面的一半
          .height(50) // 按钮高度为 50
          .margin(10) // 按钮外边距
          .onClick(() => {
            // 删除选中的水果项
            for (const deleteIndex of this.delete_Index.sort((a, b) => b - a)) {
              this.message_toList.splice(deleteIndex, 1); // 按降序删除避免索引错位
            }

            // 清空选中和删除数组
            this.select_Index = [];
            this.delete_Index = [];
            this.delete_Items = [];
            this.select_Item = [];

            this.isEdit = false; // 退出编辑模式
          });
      }
    }
    .height("100%") // 页面高度为 100%
    .width("100%"); // 页面宽度为 100%
  }
}

2.1.3 源码1运行效果

2.1.3.1 运行效果,视频

水果选择与管理:基于 ArkUI 的长按编辑功能实现

2.1.3.2 运行效果,截图
  • 默认情况
    在这里插入图片描述
  • 点击“+”符号,出现滚动选择框
    在这里插入图片描述
  • 点击选择框内的内容,每种种类只能选择一个,代码设置
    在这里插入图片描述
  • 长摁“西瓜”出现删除摁钮,更改背景颜色
    在这里插入图片描述
  • 勾选选择框后的圆
    在这里插入图片描述
  • 点击删除
    在这里插入图片描述

3.结语

本文使用了以前编写过的一些知识,如ts内容中的push方法、filter方法等,以及结合新的长摁事件、弹窗选择框等内容。有新知识也有对旧知识的重新拾起。对于新的内容或没编写过的内容,后期会选择相对应的模块进行编写。
由于笔者的能力有限,创作的内容有所不足在所难免,也敬请读者包涵和指出,万分感谢!

4.定位日期

2024-11-15;
22:59;

;