# ListItemEdit **Repository Path**: ohbu/list-item-edit ## Basic Information - **Project Name**: ListItemEdit - **Description**: 本示例基于List组件,实现待办事项管理、文件管理、备忘录的等场景列表编辑效果。 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 18 - **Created**: 2025-03-15 - **Last Updated**: 2025-03-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 列表编辑效果 ### 介绍 本示例基于List组件,实现待办事项管理、文件管理、备忘录的等场景列表编辑效果。 ### 效果预览 ![](./screenshots/device/listitem_edit.gif) ##### 使用说明 - 点击添加按钮,选择需要添加的待办事项。 - 点击左侧checkbox按钮,待办事项状态变更为已完成。 - 左滑单个待办事项,点击删除按钮后,当前待办事项被删除。 ### 工程目录 ``` ├──entry/src/main/ets/ │ ├──common │ │ └──Constants.ets // 公共常量类 │ ├──entryability │ │ └──EntryAbility.ets // 程序入口类 │ ├──model │ │ └──ToDo.ets // 待办事项数据 │ ├──pages │ │ └──Index.ets // 首页 │ └──view │ └──TodoListItem.ets // 待办选项 └──entry/src/main/resources // 应用静态资源目录 ``` ### 具体实现 1. List组件绑定@State修饰的数组变量toDoData。 2. ListItem组件设置左滑动效swipeAction属性,使得单个ListItem可以进行左右滑动,并显示自定义的UIBuilder。 3. 新增/删除列表项,更新数组变量toDoData,并同时更新List组件UI。 4. 组件定义: 使用@Component装饰器定义ToDoListItem结构体组件,这是一个列表项组件。 5. 状态变量: @Link achieveData: 已完成事项数组(双向绑定) @Link toDoData: 未完成事项数组(双向绑定) @ObjectLink toDoItem: 当前待办项对象(属性级双向绑定) @State isEdited: 控制编辑状态的本地状态 6. 方法addAchieveData: 切换isCompleted状态后,在动画上下文animateTo中操作数据: 如果标记为完成,从toDoData过滤当前项并添加到achieveData 如果取消完成,则反向操作 注意这里使用push直接修改父组件数据,可能涉及ArkUI状态管理规范 7. build方法布局结构: 外层Flex容器采用水平两端对齐,垂直居中 左侧主内容区Row包含: 动态显示部分(条件渲染if控制): 非编辑状态显示复选框和文本 编辑状态显示TextInput 8. Blank()占位分隔 右侧操作按钮(编辑/确认图标) 9. 样式细节: 复选框的多种状态样式(完成时填充颜色) 文本的删除线效果通过decoration动态设置 输入框自动获取焦点的处理focusControl.requestFocus 统一的尺寸使用常量(如ITEM_HEIGHT、PADDING等) 10. 交互逻辑: 点击复选框触发状态切换和数据转移 点击"编辑"文本进入编辑模式 点击确认图标退出编辑 11. 可能存在的疑问点: @Link与@ObjectLink的区别:前者用于数组的整体替换,后者用于对象属性的监听 animateTo的作用范围是否覆盖数据操作 直接修改父组件传递的数组是否符合ArkUI状态管理规范 焦点控制focusControl的使用是否需要额外权限 需要验证这些实现是否符合鸿蒙的最新开发规范,特别是状态管理部分是否存在潜在问题。 # 以下是代码的逐段解析: ##### 组件定义与状态管理 typescript @Component export struct ToDoListItem { @Link achieveData: ToDo[]; // 已完成事项数组(双向绑定) @Link toDoData: ToDo[]; // 未完成事项数组(双向绑定) @ObjectLink toDoItem: ToDo; // 当前待办项对象(属性级绑定) @State isEdited: boolean = false; // 本地编辑状态 ###### 关键点: @Link 实现父子组件间的双向数据同步 @ObjectLink 监听对象属性变化(而非整个对象) @State 管理组件内部状态 ##### 核心方法 addAchieveData() typescript addAchieveData() { this.toDoItem.isCompleted = !this.toDoItem.isCompleted; animateTo({ duration: STYLE_CONFIG.ANIMATION_DURATION }, () => { if (this.toDoItem.isCompleted) { let tempData = this.toDoData.filter(item => item.key !== this.toDoItem.key); this.toDoData = tempData; this.achieveData.push(this.toDoItem); } else { let tempData = this.achieveData.filter(item => item.key !== this.toDoItem.key); this.achieveData = tempData; this.toDoData.push(this.toDoItem); } }); } ##### 执行流程: 切换完成状态 在动画上下文中: 从原数组过滤当前项 更新父组件数据(通过@Link) 将当前项push到目标数组 动态布局结构(build()) ###### 外层容器 typescript Flex({ justifyContent: FlexAlign.SpaceBetween, // 水平两端对齐 alignItems: ItemAlign.Center // 垂直居中 }) { // 左侧内容区 // 右侧操作区 } .width(Constant.PERCENT_FULL) // 100%宽度 .height(STYLE_CONFIG.TODO_ITEM_HEIGHT) // 固定高度 ###### 左侧内容区 typescript Row({ space: STYLE_CONFIG.ICON_GUTTER }) { if (!this.isEdited) { // 非编辑状态:复选框 + 文本 Row() { if (this.toDoItem.isCompleted) { Image($r('app.media.ic_public_ok_filled')) // 完成图标 .width(STYLE_CONFIG.IMAGE_ICON_OK_SIZE) .aspectRatio(1) .fillColor(Color.White) } } // 复选框样式控制 .backgroundColor(this.toDoItem.isCompleted ? $r('sys.color.ohos_id_color_floating_button_bg_normal') : Color.Transparent) Text(`${this.toDoItem.name}`) .decoration({ type: this.toDoItem.isCompleted ? TextDecorationType.LineThrough : TextDecorationType.None }) // 动态删除线 } else { // 编辑状态:文本输入框 TextInput({ text: `${this.toDoItem.name}` }) .onChange((value: string) => { this.toDoItem.name = value; // 实时更新数据 }) .onAppear(() => { focusControl.requestFocus('textEdit'); // 自动聚焦 }) } ##### Blank() // 占位分隔 if (this.isEdited) { Image($r('app.media.ic_public_ok_filled')) // 确认图标 .onClick(() => { this.isEdited = false; }) } else { Text($r('app.string.edit')) // 编辑按钮 .onClick(() => { this.isEdited = true; }) } } // 边距控制 .padding({ left: $r('sys.float.ohos_id_default_padding_start'), right: $r('sys.float.ohos_id_default_padding_end'), vertical: STYLE_CONFIG.TODO_ITEM_PADDING_VERTICAL }) // 视觉修饰 .borderRadius($r('sys.float.ohos_id_corner_radius_default_m')) .backgroundColor(Color.White) ##### 设计特点: 使用系统级资源标识符($r('sys...')) 常量集中管理(STYLE_CONFIG) 动态样式根据状态变化 # 交互流程图 ![img.png](img.png) ##### 关键实现技巧 状态驱动UI:通过isEdited和isCompleted控制显示差异 高效数据更新: @ObjectLink实现细粒度更新 使用filter+push替代splice提升性能 焦点管理: typescript focusControl.requestFocus('textEdit') 动画集成: typescript animateTo({ duration: 300 }, () => { // 数据操作 }) 潜在优化点 防抖处理:文本输入增加防抖避免频繁渲染 空状态处理:添加输入校验 动画细化:不同操作使用不同动画曲线 国际化:通过$r实现文本资源隔离 这个组件完整实现了待办事项的显示、状态切换、编辑修改等核心功能,符合HarmonyOS应用开发规范,可作为列表项复用的标准组件。 ### 相关权限 不涉及 ### 约束与限制 1. 本示例仅支持标准系统上运行,支持设备:华为手机。 2. HarmonyOS系统:HarmonyOS 5.0.0 Release及以上。 3. DevEco Studio版本:DevEco Studio 5.0.0 Release及以上。 4. HarmonyOS SDK版本:HarmonyOS 5.0.0 Release SDK及以上。