HarmonyOS鸿蒙Next中待办事项列表应该如何打造?

HarmonyOS鸿蒙Next中待办事项列表应该如何打造? 如何快速的打造一个待办事项列表清单 ?

5 回复

只用一个 list 组件和 textInput 组件加上一点持久化就可以打造最简单的待办清单,但也只能自己测试用(如果你真的需要的话)。

更多关于HarmonyOS鸿蒙Next中待办事项列表应该如何打造?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


场景介绍

对于待办事项列表实际的实现就是TODO list ,在很多场景下都需要用到,最常见的比如工作任务、比如事项提醒等业务情况,都需要使用。

本次我们实现 一个待办事项列表清单,包括添加清单、删除清单、完成清单、清除已完成。

实现效果

完整实现代码

import preferences from '@ohos.data.preferences';
import { common } from '@kit.AbilityKit';

interface TodoItem {
  id: number;
  text: string;
  completed: boolean;
}

@Entry
@Component
struct TodoApp {
  @State todos: TodoItem[] = [];
  @State newTodoText: string = '';
  private prefs: preferences.Preferences = null!;
  private nextId: number = 1;
  private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;

  aboutToAppear() {
    // 初始化本地存储
    preferences.getPreferences(this.context,'todo_app', (err, prefs) => {
      if (!err) {
        this.prefs = prefs;
        // 读取保存的待办列表
        prefs.get('todos', '[]', (err, value) => {
          if (!err) {
            try {
              const saved:TodoItem[] = JSON.parse(value as string);
              this.todos = saved;
              // 更新 nextId,避免 ID 冲突
              if (saved.length > 0) {
                this.nextId = Math.max(...saved.map(t => t.id)) + 1;
              }
            } catch (e) {
              console.error('Failed to parse todos:', e);
            }
          }
        });
      }
    });
  }

  private saveTodos() {
    if (this.prefs) {
      this.prefs.put('todos', JSON.stringify(this.todos), () => {});
      this.prefs.flush(() => {});
    }
  }

  private addTodo() {
    if (this.newTodoText.trim() === '') return;
    this.todos.push({
      id: this.nextId++,
      text: this.newTodoText.trim(),
      completed: false
    });
    this.newTodoText = '';
    this.saveTodos();
  }

  private toggleCompleted(id: number) {
    this.todos = this.todos.map(todo =>{
      if (todo.id === id) {
        return {
          id: todo.id,
          text: todo.text,
          completed: !todo.completed,
        };
      }
      return todo;
    });
    this.saveTodos();
  }

  private deleteTodo(id: number) {
    this.todos = this.todos.filter(todo => todo.id !== id);
    this.saveTodos();
  }

  private clearCompleted() {
    this.todos = this.todos.filter(todo => !todo.completed);
    this.saveTodos();
  }

  build() {
    Column({ space: 15 }) {
      Text('我的待办')
        .fontSize(26)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 20 })

      // 输入框 + 添加按钮
      Row() {
        TextInput({ placeholder: '输入新任务...' })
          .onChange((value) => {
            this.newTodoText = value;
          })
          .onSubmit(() => {
            this.addTodo();
          })
          .width('75%')
          .height(45)
          .backgroundColor('#F5F5F5')
          .borderRadius(8)

        Button('添加')
          .width('20%')
          .height(45)
          .backgroundColor('#007DFF')
          .fontColor(Color.White)
          .onClick(() => {
            this.addTodo();
          })
      }
      .width('90%')

      // 任务列表
      List({ space: 10 }) {
        ForEach(
          this.todos,
          (item: TodoItem) => {
            ListItem() {
              Row() {
                Checkbox({ name: 'todo', group: 'todos' })
                  .select(item.completed)
                  .onChange((isChecked) => {
                    this.toggleCompleted(item.id);
                  })

                Text(item.text)
                  .decoration({type:item.completed ? TextDecorationType.LineThrough : TextDecorationType.None})
                  .layoutWeight(1)
                  .margin({ left: 10 })

                Button('删除')
                  .width(60)
                  .height(30)
                  .fontColor(Color.White)
                  .backgroundColor('#FF4D4F')
                  .onClick(() => {
                    this.deleteTodo(item.id);
                  })
              }
              .padding(12)
              .width('100%')
              .borderRadius(8)
              .backgroundColor('#FAFAFA')
            }
          }
        )
      }
      .layoutWeight(1)
      .width('90%')
      .margin({ top: 10 })

      // 清空已完成按钮
      if (this.todos.some(t => t.completed)) {
        Button('清空已完成')
          .width(200)
          .height(40)
          .backgroundColor('#FFA500')
          .fontColor(Color.White)
          .margin({ bottom: 20 })
          .onClick(() => {
            this.clearCompleted();
          })
      }
    }
    .width('100%')
    .height('100%')
  }
}

在HarmonyOS Next中打造待办事项列表

主要使用ArkTS声明式UI开发。通过List组件构建列表项,结合ForEach渲染数据。数据管理推荐使用@State@Observed装饰器进行状态管理,确保UI响应式更新。持久化存储可选用轻量级偏好数据库或关系型数据库。界面交互通过手势事件或自定义弹窗实现增删改查功能。

在HarmonyOS Next中快速打造待办事项列表,核心在于利用其声明式UI开发范式ArkTS和高效的开发工具。以下是关键步骤和要点:

  1. 项目与页面搭建

    • 使用DevEco Studio创建Empty Ability项目。
    • pages目录下创建待办事项主页面(如TodoListPage.ets),利用@Entry装饰器标记为入口组件。
  2. 数据模型定义

    • 定义待办事项数据类(如TodoItem),包含idtitleisCompleted等属性。
    • 使用@State@Provide装饰器管理列表数据,确保数据变化驱动UI自动刷新。
  3. UI界面构建

    • 使用List组件展示待办事项列表,通过ForEach循环渲染每个TodoItem
    • 每个列表项可包含Checkbox(标记完成状态)、Text(显示标题)和Button(删除操作)。
    • 添加TextInputButton作为输入区域,用于新增待办事项。
  4. 交互功能实现

    • 新增:在输入框绑定onSubmit或按钮绑定onClick事件,将新事项添加到数据数组。
    • 删除:为删除按钮绑定事件,通过splice方法从数据数组中移除对应项。
    • 状态切换:为Checkbox绑定onChange事件,更新对应事项的isCompleted值。
  5. 数据持久化(可选)

    • 使用Preferences或关系型数据库存储列表数据,在aboutToAppear生命周期初始化数据,在aboutToDisappear保存数据。

示例代码片段(核心逻辑):

@Entry
@Component
struct TodoListPage {
  @State todoList: TodoItem[] = []
  @State newTitle: string = ''

  build() {
    Column() {
      // 输入区域
      Row() {
        TextInput({ placeholder: '输入新事项' })
          .onChange((value: string) => { this.newTitle = value })
        Button('添加').onClick(() => {
          if (this.newTitle) {
            this.todoList.push(new TodoItem(this.newTitle))
            this.newTitle = ''
          }
        })
      }

      // 列表区域
      List() {
        ForEach(this.todoList, (item: TodoItem) => {
          ListItem() {
            Row() {
              Checkbox({ selected: item.isCompleted })
                .onChange((checked: boolean) => { item.isCompleted = checked })
              Text(item.title).decoration({ type: item.isCompleted ? TextDecorationType.LineThrough : TextDecorationType.None })
              Button('删除').onClick(() => {
                let index = this.todoList.indexOf(item)
                this.todoList.splice(index, 1)
              })
            }
          }
        })
      }
    }
  }
}

优化建议

  • 使用@Link@ObjectLink实现组件间数据同步。
  • 通过ListItemswipeAction属性添加左滑删除等交互。
  • 结合Flex布局和组件样式美化界面。

按照以上步骤,可在30分钟内完成一个具备增删改查功能的待办事项列表。HarmonyOS Next的声明式开发模式能极大提升此类交互界面的开发效率。

回到顶部