代码功能概述
这段代码实现了一个功能完整的鸿蒙待办事项应用,全面展示了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 面向对象核心的类和对象、继承多态,到吃透鸿蒙开发关键技能,还能冲刺鸿蒙基础 +高级开发者证书,更惊喜的是考证成功还送好礼!快加入我的鸿蒙班,一起从入门到精通,班级链接:点击免费进入

1744

被折叠的 条评论
为什么被折叠?



