HarmonyOS 应用 · 班级任务首页深度解析:Progress 环形进度与 toggle 勾选刷新
HarmonyOS 应用 · 班级任务首页深度解析:Progress 环形进度与 toggle 勾选刷新
项目编号:48-class-task 技术栈:HarmonyOS ArkTS · ArkUI 声明式 UI · Stage 模型 本篇页面:首页
HomeTab.ets(103 行) 系列导航:(一)首页 · (二)任务 · (三)进度 · (四)我的

一、Theme.ets:紫色主题与任务管理产品的色彩语义
export class C {
static readonly bg: string = '#F2F5FB';
static readonly card: string = '#FFFFFF';
static readonly cardSoft: string = '#F4F6FB';
static readonly stroke: string = '#EAEEF6';
static readonly text: string = '#1C2333';
static readonly textSub: string = '#5A6483';
static readonly textDim: string = '#9AA3BC';
static readonly primary: string = '#6C5CE7';
static readonly primarySoft: string = '#ECE8FD';
static readonly accent: string = '#9B8AF5';
static readonly warn: string = '#FF9F1C';
static readonly danger: string = '#FF5A6E';
static readonly ok: string = '#2BB673';
}
班级任务的主色是 #6C5CE7(深紫),与班费管理的 #00A862(翡翠绿)、通讯录的 #0984E3(亮蓝)形成区分。紫色传递"任务/协作/管理"的色彩语义——任务管理是协调型应用,紫色比绿色更中性、比蓝色更有调度感。primarySoft(#ECE8FD)是浅紫底色,做头像背景。
二、Index.ets:Tabs 容器与四 Tab 布局
Tabs({ barPosition: BarPosition.End, index: this.current }) {
TabContent() { HomeTab() }.tabBar(this.bar('首页', '📋', 0))
TabContent() { Func1Tab() }.tabBar(this.bar('任务', '✏️', 1))
TabContent() { Func2Tab() }.tabBar(this.bar('进度', '📊', 2))
TabContent() { ProfileTab() }.tabBar(this.bar('我的', '👤', 3))
}
.barBackgroundColor('#FFFFFF')
.barHeight(60 + this.safeBottom)
.scrollable(false)
.onChange((idx: number) => { this.current = idx; })
.width('100%').height('100%').backgroundColor(C.bg)
四个 Tab:首页(📋)/任务(✏️)/进度(📊)/我的(👤)。任务管理的四个环节:查看今日任务 → 创建新任务 → 查看成员进度 → 个人统计。
三、Task interface 与 @State tasks 数组
interface Task {
id: number;
emoji: string;
title: string;
owner: string;
deadline: string;
done: boolean;
}
六个字段:id 是 key 锚点,emoji 是任务图标,title 是任务标题,owner 是负责人,deadline 是截止时间,done 是"是否完成"的布尔位。done 是首页的核心状态字段——驱动勾选符号、标题颜色、删除线三态变化。
@State tasks: Task[] = [
{ id: 1, emoji: '📋', title: '收齐班费并登记', owner: '生活委员', deadline: '今天', done: false },
{ id: 2, emoji: '📢', title: '发布运动会通知', owner: '宣传委员', deadline: '今天', done: true },
{ id: 3, emoji: '📝', title: '统计社会实践报名', owner: '学习委员', deadline: '明天', done: false },
{ id: 4, emoji: '🎉', title: '筹备班级团建', owner: '文娱委员', deadline: '本周', done: false }
];
@State tasks 是 @State 修饰的数组——与普通 private 不同,@State 让数组引用变化时触发 UI 刷新。四条任务:1 项已完成(发布运动会通知)+ 3 项待完成。
四、doneCount 与 toggle:不可变更新模式
private doneCount(): number {
let n = 0;
this.tasks.forEach((t: Task) => { if (t.done) { n++; } });
return n;
}
private toggle(item: Task): void {
item.done = !item.done;
this.tasks = this.tasks.slice();
}
doneCount() 遍历 tasks 统计已完成数——每次调用都重新计算,保证进度始终最新。
toggle(item) 是首页的核心交互方法——两步不可变更新:
// 1. 翻转 done 布尔位
item.done = !item.done;
// 2. slice() 生成新数组引用,触发 @State 刷新
this.tasks = this.tasks.slice();
slice() 无参调用返回数组浅拷贝——新引用触发 @State 重新渲染,ProgressCard 的环形进度和 TaskList 的勾选态同步刷新。这是 ArkUI 中数组状态更新的标准范式。
五、ProgressCard:Progress 环形组件 + 渐变背景
@Builder
ProgressCard() {
Row({ space: 16 }) {
Stack({ alignContent: Alignment.Center }) {
Progress({ value: this.doneCount(), total: this.tasks.length, type: ProgressType.Ring })
.width(64).height(64).color('#FFFFFF').style({ strokeWidth: 6 }).backgroundColor('#44FFFFFF')
Text(this.doneCount() + '/' + this.tasks.length).fontSize(14).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
}
Column({ space: 4 }) {
Text('今日任务进度').fontSize(16).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
Text('还有 ' + (this.tasks.length - this.doneCount()) + ' 项待完成').fontSize(12).fontColor('#FFFFFF').opacity(0.9)
}.alignItems(HorizontalAlign.Start).layoutWeight(1)
}
.width('100%').padding(18).borderRadius(D.rLg)
.linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] })
}
Progress 组件——系列首次出现的环形进度:
Progress({ value: this.doneCount(), total: this.tasks.length, type: ProgressType.Ring })
.width(64).height(64).color('#FFFFFF').style({ strokeWidth: 6 }).backgroundColor('#44FFFFFF')
ProgressType.Ring 环形进度条,value 是当前值(doneCount),total 是总数(tasks.length)。color('#FFFFFF') 白色进度环 + backgroundColor('#44FFFFFF') 半透明底环——在紫色渐变背景上白环可见。style({ strokeWidth: 6 }) 环宽 6px。
Stack 叠加:环形 Progress + 中心文字"1/4"——Alignment.Center 让文字居中在环内。右侧"今日任务进度" + "还有 3 项待完成",this.tasks.length - this.doneCount() 动态计算待完成数。
六、TaskList:done 驱动的勾选 + 删除线双态
@Builder
TaskList() {
Column({ space: 10 }) {
ForEach(this.tasks, (t: Task) => {
Row({ space: 12 }) {
Text(t.done ? '✅' : '⬜').fontSize(22).onClick(() => { this.toggle(t); })
Column({ space: 4 }) {
Text(t.title).fontSize(14).fontColor(t.done ? C.textDim : C.text)
.decoration({ type: t.done ? TextDecorationType.LineThrough : TextDecorationType.None })
Text('负责人: ' + t.owner + ' · ' + t.deadline).fontSize(12).fontColor(C.textDim)
}.alignItems(HorizontalAlign.Start).layoutWeight(1)
Text(t.emoji).fontSize(20)
}
.width('100%').padding(14).backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke })
}, (t: Task) => t.id.toString())
}.width('100%')
}
done 驱动三元变化——勾选符号、标题颜色、删除线三路分支:
// 勾选符号:✅ vs ⬜
Text(t.done ? '✅' : '⬜')
// 标题颜色:灰色 vs 深色
.fontColor(t.done ? C.textDim : C.text)
// 删除线:有 vs 无
.decoration({ type: t.done ? TextDecorationType.LineThrough : TextDecorationType.None })
done === true 时 ✅ + 灰色标题 + 删除线(已完成视觉弱化),done === false 时 ⬜ + 深色标题 + 无删除线(待完成视觉突出)。TextDecorationType.LineThrough 是 ArkUI 的删除线装饰——已完成任务的经典视觉表达。
勾选符号 onClick 调 this.toggle(t)——点击翻转 done + slice() 触发刷新,ProgressCard 环形进度和 TaskList 勾选态同步更新。



七、可演进方向
| 方向 | 现状 | 改法 | 收益 |
|---|---|---|---|
| 任务创建 | 静态 4 条 | 接入任务 Tab 创建后追加 | 任务动态新增 |
| 数据持久 | @State 内存 | Preferences 持久化 | 重启不丢失 |
| 过期检测 | 无 | 比对 deadline 与当前日期 | 过期任务标红 |
| 拖拽排序 | 无 | ItemTouchHelper 拖拽 | 任务优先级手动调整 |
| 任务详情 | 无 onClick | 点击进入详情页 | 展示完整描述 |
首页是班级任务的概览——ProgressCard 的环形进度 + TaskList 的 done 驱动勾选双态。从 toggle 的不可变更新到 TextDecorationType.LineThrough 的删除线装饰,每一层都有明确的职责边界。

更多推荐



所有评论(0)