核心功能
- 添加待辦事項 - 創建新的待辦任務,包含標題、描述、優先級、截止日期
- 查看任務列表 - 以卡片形式展示所有待辦事項
- 標記完成狀態 - 將任務標記為已完成/未完成
- 編輯任務 - 修改已保存的任務信息
- 刪除任務 - 刪除不需要的任務
- 任務篩選 - 按狀態篩選查看任務
- 任務統計 - 統計總任務數、已完成數和未完成數
技術特點
- 使用ArkTS聲明式UI開發
- 採用MVVM架構模式
- 組件化設計
- 本地數據存儲(內存中)
- 響應式數據綁定
- 支持任務優先級管理
完整源代碼
// 簡易待辦事項管理應用
// 文件名:TodoManager.ets
import promptAction from '@ohos.promptAction';
// 待辦事項數據模型
class TodoItem {
id: number = 0;
title: string = '';
description: string = '';
completed: boolean = false;
priority: number = 1; // 1-低, 2-中, 3-高
dueDate: string = '';
createTime: string = '';
constructor(id: number, title: string = '', description: string = '',
completed: boolean = false, priority: number = 1,
dueDate: string = '', createTime: string = '') {
this.id = id;
this.title = title;
this.description = description;
this.completed = completed;
this.priority = priority;
this.dueDate = dueDate;
this.createTime = createTime;
}
}
@Entry
@Component
struct TodoManager {
// 待辦事項列表
@State todoList: TodoItem[] = [];
// 任務統計
@State totalCount: number = 0;
@State completedCount: number = 0;
@State pendingCount: number = 0;
// 編輯相關狀態
@State currentItem: TodoItem = new TodoItem(0);
@State showEditDialog: boolean = false;
@State isEditing: boolean = false;
// 篩選狀態
@State filterStatus: string = '全部'; // 全部、未完成、已完成
// 優先級選項
@State priorities: string[] = ['低優先級', '中優先級', '高優先級'];
// 組件生命週期
aboutToAppear() {
this.initSampleData();
this.calculateStatistics();
}
// 初始化示例數據
initSampleData() {
const today = new Date();
const tomorrow = new Date(today);
tomorrow.setDate(tomorrow.getDate() + 1);
this.todoList = [
new TodoItem(1, '學習ArkTS', '完成HarmonyOS應用開發學習', false, 3, this.formatDate(tomorrow), '2024-01-15'),
new TodoItem(2, '購物', '去超市購買生活用品', true, 1, '2024-01-14', '2024-01-13'),
new TodoItem(3, '健身', '健身房鍛鍊1小時', false, 2, '2024-01-16', '2024-01-14'),
new TodoItem(4, '工作會議', '項目進度彙報會議', false, 3, '2024-01-15 14:00', '2024-01-12'),
new TodoItem(5, '閲讀書籍', '閲讀《編程之美》', true, 2, '2024-01-13', '2024-01-10')
];
}
// 構建主界面
build() {
Column({ space: 0 }) {
// 頂部標題欄
this.buildHeader()
// 任務統計卡片
this.buildStatisticsCard()
// 篩選欄
this.buildFilterBar()
// 任務列表
this.buildTodoList()
}
.width('100%')
.height('100%')
.backgroundColor('#F5F7FA')
}
// 頂部標題欄
@Builder
buildHeader() {
Row() {
Text('待辦事項管理')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.fontColor('#FFFFFF')
.layoutWeight(1)
Button('+ 新建')
.width(80)
.height(35)
.fontSize(14)
.backgroundColor('#FFFFFF')
.fontColor('#007DFF')
.onClick(() => {
this.addNewItem();
})
}
.width('100%')
.padding({ left: 20, right: 20, top: 15, bottom: 15 })
.backgroundColor('#007DFF')
}
// 任務統計卡片
@Builder
buildStatisticsCard() {
Row() {
// 總任務數
Column({ space: 4 }) {
Text(this.totalCount.toString())
.fontSize(24)
.fontWeight(FontWeight.Bold)
.fontColor('#007DFF')
Text('總任務')
.fontSize(12)
.fontColor('#666666')
}
.layoutWeight(1)
// 已完成數
Column({ space: 4 }) {
Text(this.completedCount.toString())
.fontSize(24)
.fontWeight(FontWeight.Bold)
.fontColor('#4CAF50')
Text('已完成')
.fontSize(12)
.fontColor('#666666')
}
.layoutWeight(1)
// 未完成數
Column({ space: 4 }) {
Text(this.pendingCount.toString())
.fontSize(24)
.fontWeight(FontWeight.Bold)
.fontColor('#FF9800')
Text('未完成')
.fontSize(12)
.fontColor('#666666')
}
.layoutWeight(1)
}
.width('90%')
.padding(20)
.backgroundColor('#FFFFFF')
.borderRadius(12)
.margin({ top: 20, bottom: 20 })
.shadow({ radius: 4, color: '#E0E0E0', offsetX: 1, offsetY: 2 })
}
// 篩選欄
@Builder
buildFilterBar() {
Row({ space: 10 }) {
Button('全部')
.width(80)
.height(35)
.fontSize(14)
.backgroundColor(this.filterStatus === '全部' ? '#007DFF' : '#FFFFFF')
.fontColor(this.filterStatus === '全部' ? '#FFFFFF' : '#666666')
.onClick(() => {
this.filterStatus = '全部';
})
Button('未完成')
.width(80)
.height(35)
.fontSize(14)
.backgroundColor(this.filterStatus === '未完成' ? '#FF9800' : '#FFFFFF')
.fontColor(this.filterStatus === '未完成' ? '#FFFFFF' : '#666666')
.onClick(() => {
this.filterStatus = '未完成';
})
Button('已完成')
.width(80)
.height(35)
.fontSize(14)
.backgroundColor(this.filterStatus === '已完成' ? '#4CAF50' : '#FFFFFF')
.fontColor(this.filterStatus === '已完成' ? '#FFFFFF' : '#666666')
.onClick(() => {
this.filterStatus = '已完成';
})
}
.width('100%')
.justifyContent(FlexAlign.Center)
.margin({ bottom: 15 })
}
// 任務列表
@Builder
buildTodoList() {
List({ space: 12 }) {
ForEach(this.getFilteredItems(), (item: TodoItem) => {
ListItem() {
this.buildTodoItem(item)
}
})
}
.width('100%')
.layoutWeight(1)
.padding({ left: 16, right: 16 })
// 編輯對話框
if (this.showEditDialog) {
this.buildEditDialog()
}
}
// 任務項組件
@Builder
buildTodoItem(item: TodoItem) {
Column({ space: 8 }) {
// 第一行:標題和優先級
Row() {
// 完成狀態複選框
Checkbox({ name: 'completed', group: 'todo' + item.id })
.select(item.completed)
.selectedColor('#4CAF50')
.width(20)
.height(20)
.onChange((checked: boolean) => {
this.toggleComplete(item.id, checked);
})
// 標題
Text(item.title)
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor(item.completed ? '#999999' : '#333333')
.decoration({ type: item.completed ? TextDecorationType.LineThrough : TextDecorationType.None })
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.layoutWeight(1)
.margin({ left: 10 })
// 優先級標籤
Text(this.priorities[item.priority - 1])
.fontSize(12)
.padding({ left: 6, right: 6, top: 2, bottom: 2 })
.backgroundColor(this.getPriorityColor(item.priority, item.completed))
.fontColor('#FFFFFF')
.borderRadius(4)
}
.width('100%')
// 第二行:描述
if (item.description) {
Row() {
Text(item.description)
.fontSize(14)
.fontColor(item.completed ? '#AAAAAA' : '#666666')
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
.width('100%')
.margin({ left: 30 })
}
// 第三行:日期信息和操作按鈕
Row() {
// 截止日期
if (item.dueDate) {
Row() {
Image($rawfile('calendar.png'))
.width(14)
.height(14)
.margin({ right: 4 })
Text(item.dueDate)
.fontSize(12)
.fontColor(item.completed ? '#AAAAAA' : '#FF5722')
}
.layoutWeight(1)
} else {
Blank()
.layoutWeight(1)
}
// 操作按鈕
Row({ space: 8 }) {
Button('編輯')
.width(60)
.height(28)
.fontSize(12)
.backgroundColor('#2196F3')
.onClick(() => {
this.editItem(item);
})
Button('刪除')
.width(60)
.height(28)
.fontSize(12)
.backgroundColor('#FF5722')
.onClick(() => {
this.deleteItem(item.id);
})
}
}
.width('100%')
.margin({ left: 30, top: 8 })
}
.width('100%')
.padding(16)
.backgroundColor('#FFFFFF')
.borderRadius(10)
.border({ width: 1, color: item.completed ? '#E0E0E0' : this.getPriorityColor(item.priority, false) })
.shadow({ radius: 2, color: '#E0E0E0', offsetX: 1, offsetY: 1 })
}
// 編輯對話框
@Builder
buildEditDialog() {
Column() {
// 標題
Text(this.isEditing ? '編輯任務' : '新建任務')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin({ top: 20, bottom: 16 })
// 任務標題
TextInput({ placeholder: '任務標題(必填)', text: this.currentItem.title })
.width('90%')
.height(45)
.fontSize(16)
.margin({ bottom: 12 })
.onChange((value: string) => {
this.currentItem.title = value;
})
// 任務描述
TextInput({ placeholder: '任務描述(可選)', text: this.currentItem.description })
.width('90%')
.height(60)
.fontSize(16)
.margin({ bottom: 12 })
.onChange((value: string) => {
this.currentItem.description = value;
})
// 優先級選擇
Row() {
Text('優先級:')
.fontSize(16)
.fontColor('#666666')
.margin({ right: 10 })
ForEach(this.priorities, (priority: string, index: number) => {
Text(priority)
.fontSize(14)
.padding({ left: 12, right: 12, top: 6, bottom: 6 })
.backgroundColor(this.currentItem.priority === (index + 1) ? this.getPriorityColor(index + 1, false) : '#F0F0F0')
.fontColor(this.currentItem.priority === (index + 1) ? '#FFFFFF' : '#666666')
.borderRadius(8)
.margin({ right: 8 })
.onClick(() => {
this.currentItem.priority = index + 1;
})
})
}
.width('90%')
.margin({ bottom: 12 })
// 截止日期
TextInput({ placeholder: '截止日期(如:2024-01-20)', text: this.currentItem.dueDate })
.width('90%')
.height(45)
.fontSize(16)
.margin({ bottom: 20 })
.onChange((value: string) => {
this.currentItem.dueDate = value;
})
// 操作按鈕
Row({ space: 20 }) {
Button('取消')
.width(120)
.height(42)
.fontSize(16)
.backgroundColor('#9E9E9E')
.onClick(() => {
this.showEditDialog = false;
})
Button(this.isEditing ? '保存' : '創建')
.width(120)
.height(42)
.fontSize(16)
.backgroundColor('#007DFF')
.onClick(() => {
this.saveItem();
})
}
.margin({ bottom: 20 })
}
.width('85%')
.backgroundColor('#FFFFFF')
.borderRadius(12)
.shadow({ radius: 20, color: '#00000040' })
.position({ x: '7.5%', y: '10%' })
}
// 添加新任務
addNewItem() {
const newId = this.todoList.length > 0 ?
Math.max(...this.todoList.map(item => item.id)) + 1 : 1;
const today = this.formatDate(new Date());
this.currentItem = new TodoItem(
newId,
'',
'',
false,
2,
'',
today
);
this.isEditing = false;
this.showEditDialog = true;
}
// 編輯任務
editItem(item: TodoItem) {
this.currentItem = { ...item };
this.isEditing = true;
this.showEditDialog = true;
}
// 保存任務
saveItem() {
if (!this.currentItem.title.trim()) {
promptAction.showToast({ message: '請輸入任務標題', duration: 2000 });
return;
}
if (this.isEditing) {
// 更新現有任務
const index = this.todoList.findIndex(item => item.id === this.currentItem.id);
if (index >= 0) {
this.todoList[index] = { ...this.currentItem };
}
promptAction.showToast({ message: '任務更新成功', duration: 2000 });
} else {
// 添加新任務
this.todoList.push({ ...this.currentItem });
promptAction.showToast({ message: '任務創建成功', duration: 2000 });
}
this.showEditDialog = false;
this.calculateStatistics();
}
// 切換完成狀態
toggleComplete(id: number, completed: boolean) {
const index = this.todoList.findIndex(item => item.id === id);
if (index >= 0) {
this.todoList[index].completed = completed;
this.calculateStatistics();
}
}
// 刪除任務
deleteItem(id: number) {
promptAction.showDialog({
title: '確認刪除',
message: '確定要刪除這個任務嗎?',
buttons: [
{ text: '取消', color: '#666666' },
{ text: '刪除', color: '#FF5722' }
]
}).then((result) => {
if (result.index === 1) {
const index = this.todoList.findIndex(item => item.id === id);
if (index >= 0) {
this.todoList.splice(index, 1);
promptAction.showToast({ message: '刪除成功', duration: 2000 });
this.calculateStatistics();
}
}
});
}
// 計算統計信息
calculateStatistics() {
this.totalCount = this.todoList.length;
this.completedCount = this.todoList.filter(item => item.completed).length;
this.pendingCount = this.totalCount - this.completedCount;
}
// 獲取篩選後的任務列表
getFilteredItems(): TodoItem[] {
switch (this.filterStatus) {
case '未完成':
return this.todoList.filter(item => !item.completed);
case '已完成':
return this.todoList.filter(item => item.completed);
default:
return this.todoList;
}
}
// 獲取優先級顏色
getPriorityColor(priority: number, completed: boolean): string {
if (completed) {
return '#E0E0E0';
}
switch (priority) {
case 1: // 低優先級
return '#4CAF50';
case 2: // 中優先級
return '#FF9800';
case 3: // 高優先級
return '#FF5722';
default:
return '#2196F3';
}
}
// 格式化日期
formatDate(date: Date): string {
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
return `${year}-${month}-${day}`;
}
}
想入門鴻蒙開發又怕花冤枉錢?別錯過!現在能免費系統學 -- 從 ArkTS 面向對象核心的類和對象、繼承多態,到吃透鴻蒙開發關鍵技能,還能衝刺鴻蒙基礎 +高級開發者證書,更驚喜的是考證成功還送好禮!快加入我的鴻蒙班,一起從入門到精通,班級鏈接:點擊https://developer.huawei.com/consumer/cn/training/classDetail/b7365031334e4353a9a0fd6785bb0791?type=1?ha_source=hmosclass&ha_sourceId=89000248免費進入