【鸿蒙开发实战】HarmonyOS待办事项应用

代码功能概述

这段代码实现了一个功能完整的鸿蒙待办事项应用,全面展示了ArkTS在列表操作、本地存储和复杂状态管理等方面的核心能力。主要功能包括:

 **待办事项管理**:添加、删除、标记完成待办事项

 **智能过滤**:按全部、待完成、已完成三种状态筛选任务

 **实时统计**:动态显示任务总数、已完成和待完成数量

 **数据持久化**:模拟本地存储功能,保存任务数据

 **空状态处理**:针对不同过滤状态显示相应的提示信息

 **响应式UI**:数据变化自动驱动界面更新

代码逻辑分析

应用采用"状态驱动UI"的现代化架构设计:

1. **初始化阶段**:应用启动时,通过`aboutToAppear()`生命周期方法加载初始待办数据

2. **状态管理**:使用多个`@State`装饰器管理待办列表、输入内容和过滤状态

3. **用户交互流程**:

   - 输入文本并点击添加 → 调用`addTodo()` → 更新`todoList`数组

   - 点击复选框 → 调用`toggleTodo()` → 切换任务完成状态

   - 点击删除按钮 → 调用`deleteTodo()` → 移除指定任务

   - 切换过滤选项 → 更新`filterType` → 重新渲染过滤后的列表

4. **数据同步**:所有操作后自动调用`saveTodos()`模拟数据保存

5. **UI自动更新**:状态变化触发依赖组件的重新渲染,实现数据驱动界面

完整代码

@Entry
@Component
struct TodoTutorial {
  // @State装饰器:管理待办事项列表和状态
  @State todoList: TodoItem[] = [];
  @State newTodoText: string = '';
  @State filterType: FilterType = FilterType.ALL;

  // 生命周期:组件创建时加载数据
  aboutToAppear() {
    this.loadTodos();
  }

  build() {
    Column({ space: 0 }) {
      // 头部标题
      Text('待办事项')
        .fontSize(32)
        .fontWeight(FontWeight.Bold)
        .fontColor('#2C3E50')
        .margin({ top: 20, bottom: 20 })

      // 添加新待办
      this.BuildAddTodo()

      // 过滤选项
      this.BuildFilterOptions()

      // 待办列表
      this.BuildTodoList()

      // 统计信息
      this.BuildStats()
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .backgroundColor('#ECF0F1')
  }

  // 构建添加待办区域 - 演示TextInput和Button协同
  @Builder BuildAddTodo() {
    Row({ space: 10 }) {
      // 文本输入框
      TextInput({ placeholder: '添加新待办事项...', text: this.newTodoText })
        .onChange((value: string) => {
          this.newTodoText = value; // 实时更新输入内容
        })
        .onSubmit(() => {
          this.addTodo(); // 回车提交
        })
        .padding(10)
        .backgroundColor(Color.White)
        .borderRadius(8)
        .layoutWeight(1) // 占据剩余空间

      // 添加按钮
      Button('添加')
        .onClick(() => {
          this.addTodo();
        })
        .backgroundColor('#3498DB')
        .fontColor(Color.White)
        .padding({ left: 20, right: 20 })
        .borderRadius(8)
        .enabled(this.newTodoText.trim().length > 0) // 输入不为空时启用
    }
    .width('100%')
    .margin({ bottom: 20 })
  }

  // 构建过滤选项 - 演示单选按钮组
  @Builder BuildFilterOptions() {
    Row({ space: 15 }) {
      // 全部
      this.BuildFilterButton('全部', FilterType.ALL)
      // 未完成
      this.BuildFilterButton('待完成', FilterType.ACTIVE)
      // 已完成
      this.BuildFilterButton('已完成', FilterType.COMPLETED)
    }
    .width('100%')
    .margin({ bottom: 15 })
  }

  // 构建过滤按钮 - 演示参数化Builder
  @Builder BuildFilterButton(text: string, filter: FilterType) {
    Button(text)
      .onClick(() => {
        this.filterType = filter;
      })
      .backgroundColor(this.filterType === filter ? '#3498DB' : '#BDC3C7')
      .fontColor(Color.White)
      .padding({ left: 15, right: 15 })
      .borderRadius(15)
      .height(30)
  }

  // 构建待办列表 - 修复:在UI描述中不能包含逻辑代码
  @Builder BuildTodoList() {
    Column() {
      if (this.getFilteredTodos().length === 0) {
        // 空状态提示
        this.BuildEmptyState()
      } else {
        // 列表内容 - 使用List组件实现滚动
        List() {
          // ForEach必须在List内部使用
          ForEach(this.getFilteredTodos(), (todo: TodoItem) => {
            ListItem() {
              this.BuildTodoItem(todo)
            }
          }, (todo: TodoItem) => todo.id.toString())
        }
        .width('100%')
        .layoutWeight(1) // 占据剩余空间
        .backgroundColor(Color.Transparent)
      }
    }
    .width('100%')
    .layoutWeight(1) // 重要:让列表区域可滚动
  }

  // 构建空状态 - 演示条件渲染
  @Builder BuildEmptyState() {
    Column({ space: 15 }) {
      // 使用Unicode字符代替图片资源
      Text('📝')
        .fontSize(48)
        .opacity(0.5)

      Text(this.getEmptyStateText())
        .fontSize(18)
        .fontColor('#7F8C8D')
        .textAlign(TextAlign.Center)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }

  // 构建单个待办项 - 演示复杂交互
  @Builder BuildTodoItem(todo: TodoItem) {
    Row({ space: 12 }) {
      // 完成状态切换
      Checkbox({ name: 'todo', group: 'todos' })
        .onChange((value: boolean) => {
          this.toggleTodo(todo.id);
        })
        .select(todo.completed)
        .width(20)
        .height(20)

      // 待办文本
      Text(todo.text)
        .fontSize(18)
        .fontColor(todo.completed ? '#95A5A6' : '#2C3E50')
        .decoration({ type: todo.completed ? TextDecorationType.LineThrough : TextDecorationType.None })
        .layoutWeight(1) // 文本占据剩余空间
        .textAlign(TextAlign.Start)

      // 删除按钮
      Button('删除')
        .onClick(() => {
          this.deleteTodo(todo.id);
        })
        .backgroundColor('#E74C3C')
        .fontColor(Color.White)
        .padding({ left: 12, right: 12 })
        .borderRadius(6)
        .height(30)
    }
    .width('100%')
    .padding(15)
    .backgroundColor(Color.White)
    .borderRadius(10)
    .shadow({ radius: 2, color: '#000000', offsetX: 0, offsetY: 1 })
  }

  // 构建统计信息 - 演示计算属性
  @Builder BuildStats() {
    Row({ space: 20 }) {
      Text(`总计: ${this.todoList.length}`)
        .fontSize(14)
        .fontColor('#2C3E50')

      Text(`已完成: ${this.getCompletedCount()}`)
        .fontSize(14)
        .fontColor('#27AE60')

      Text(`待完成: ${this.getActiveCount()}`)
        .fontSize(14)
        .fontColor('#E67E22')
    }
    .width('100%')
    .margin({ top: 15 })
    .padding(15)
    .backgroundColor(Color.White)
    .borderRadius(10)
  }

  // 添加新待办 - 修复:使用concat替代展开运算符
  private addTodo(): void {
    if (this.newTodoText.trim().length === 0) return;

    const newTodo: TodoItem = {
      id: Date.now(), // 使用时间戳作为ID
      text: this.newTodoText.trim(),
      completed: false,
      createdAt: new Date()
    };

    // 修复:使用concat方法替代展开运算符
    this.todoList = this.todoList.concat([newTodo]);
    this.newTodoText = ''; // 清空输入框
    this.saveTodos();
  }

  // 切换完成状态 - 修复:使用map创建新数组
  private toggleTodo(id: number): void {
    // 修复:直接返回新数组,不使用展开运算符
    const newList: TodoItem[] = [];
    for (let i = 0; i < this.todoList.length; i++) {
      const todo = this.todoList[i];
      if (todo.id === id) {
        // 创建新对象而不是修改原对象
        newList.push({
          id: todo.id,
          text: todo.text,
          completed: !todo.completed,
          createdAt: todo.createdAt
        });
      } else {
        newList.push(todo);
      }
    }
    this.todoList = newList;
    this.saveTodos();
  }

  // 删除待办 - 修复:使用filter方法
  private deleteTodo(id: number): void {
    // filter方法在ArkTS中是可用的
    this.todoList = this.todoList.filter((todo: TodoItem) => todo.id !== id);
    this.saveTodos();
  }

  // 获取过滤后的列表
  private getFilteredTodos(): TodoItem[] {
    switch (this.filterType) {
      case FilterType.ACTIVE:
        return this.todoList.filter((todo: TodoItem) => !todo.completed);
      case FilterType.COMPLETED:
        return this.todoList.filter((todo: TodoItem) => todo.completed);
      default:
        return this.todoList;
    }
  }

  // 获取空状态文本
  private getEmptyStateText(): string {
    switch (this.filterType) {
      case FilterType.ACTIVE:
        return '没有待完成的事项';
      case FilterType.COMPLETED:
        return '还没有完成的事项';
      default:
        return '还没有待办事项,添加一个吧!';
    }
  }

  // 统计方法
  private getCompletedCount(): number {
    return this.todoList.filter((todo: TodoItem) => todo.completed).length;
  }

  private getActiveCount(): number {
    return this.todoList.filter((todo: TodoItem) => !todo.completed).length;
  }

  // 模拟本地存储
  private saveTodos(): void {
    // 实际项目中会使用PersistentStorage
    console.log('保存待办事项:', this.todoList);
  }

  private loadTodos(): void {
    // 模拟加载数据 - 使用数组字面量而不是展开运算符
    this.todoList = [
      { id: 1, text: '学习ArkTS基础', completed: true, createdAt: new Date() },
      { id: 2, text: '完成待办事项应用', completed: false, createdAt: new Date() },
      { id: 3, text: '阅读鸿蒙文档', completed: false, createdAt: new Date() }
    ];
  }
}

// 待办项数据模型
class TodoItem {
  id: number = 0;
  text: string = '';
  completed: boolean = false;
  createdAt: Date = new Date();
}

// 过滤类型枚举
enum FilterType {
  ALL,
  ACTIVE,
  COMPLETED
}

想入门鸿蒙开发又怕花冤枉钱?别错过!现在能免费系统学 -- 从 ArkTS 面向对象核心的类和对象、继承多态,到吃透鸿蒙开发关键技能,还能冲刺鸿蒙基础 +高级开发者证书,更惊喜的是考证成功还送好礼!快加入我的鸿蒙班,一起从入门到精通,班级链接:点击免费进入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值