HarmonyOS 应用 · 班级任务进度页深度解析:Progress 线性条与达标变色
项目编号:48-class-task 技术栈:HarmonyOS ArkTS · ArkUI 声明式 UI · Stage 模型 本篇页面:进度页
Func2Tab.ets(99 行) 系列导航:(一)首页 · (二)任务 ·(三)进度· (四)我的
一、MemberProgress interface 与 percent 方法
interface MemberProgress { id: number; emoji: string; name: string; done: number; total: number; }五个字段:id是 key 锚点,emoji是头像,name是姓名,done是已完成数,total是总任务数。与首页Task.done的布尔位不同,进度页用done/total数值对——量化每个成员的完成进度。
private members: MemberProgress[] = [ { id: 1, emoji: '🧑', name: '李班长', done: 8, total: 8 }, { id: 2, emoji: '👩', name: '王学委', done: 5, total: 6 }, { id: 3, emoji: '🧑💼', name: '陈生委', done: 3, total: 5 }, { id: 4, emoji: '👨', name: '刘宣委', done: 4, total: 4 }, { id: 5, emoji: '👩', name: '张文委', done: 2, total: 5 } ]; private percent(m: MemberProgress): number { return Math.round(m.done * 100 / m.total); }五位成员:李班长 8/8(100%)、王学委 5/6(83%)、陈生委 3/5(60%)、刘宣委 4/4(100%)、张文委 2/5(40%)。percent(m)用Math.round四舍五入——5/6 = 83.33% → 83%。
二、页面骨架:OverallCard + MemberList
build() { Column() { this.Header() Scroll() { Column({ space: 14 }) { this.OverallCard() this.SectionTitle('成员完成情况') this.MemberList() } .width('100%') .padding({ left: D.pad, right: D.pad, top: 14, bottom: D.pad + this.safeBottom + 20 }) } .layoutWeight(1).scrollBar(BarState.Off).align(Alignment.Top) } .width('100%').height('100%').backgroundColor(C.bg) }Header 在 Scroll 外固定,Scroll 内三块:OverallCard(三色概览)+ SectionTitle(分区标题)+ MemberList(成员进度列表)。
三、OverallCard:三色统计概览
@Builder OverallCard() { Row() { Column({ space: 4 }) { Text('28').fontSize(22).fontWeight(FontWeight.Bold).fontColor(C.primary) Text('总任务').fontSize(11).fontColor(C.textDim) }.layoutWeight(1) Column({ space: 4 }) { Text('22').fontSize(22).fontWeight(FontWeight.Bold).fontColor(C.ok) Text('已完成').fontSize(11).fontColor(C.textDim) }.layoutWeight(1) Column({ space: 4 }) { Text('79%').fontSize(22).fontWeight(FontWeight.Bold).fontColor(C.accent) Text('完成率').fontSize(11).fontColor(C.textDim) }.layoutWeight(1) } .width('100%').padding({ top: 16, bottom: 16 }).backgroundColor(C.card).borderRadius(D.rLg).border({ width: 1, color: C.stroke }) }三色统计——总任务紫(C.primary)、已完成绿(C.ok)、完成率浅紫(C.accent)。28 = 8+6+5+4+5(各成员 total 之和),22 = 8+5+3+4+2(各成员 done 之和),79% = round(22/28*100)。
四、MemberList:Progress 线性条 + 达标变色
@Builder MemberList() { Column({ space: 12 }) { ForEach(this.members, (m: MemberProgress) => { Row({ space: 12 }) { Row() { Text(m.emoji).fontSize(22) } .width(44).height(44).backgroundColor(C.primarySoft).borderRadius(22).justifyContent(FlexAlign.Center) Column({ space: 6 }) { Row() { Text(m.name).fontSize(14).fontWeight(FontWeight.Medium).fontColor(C.text).layoutWeight(1) Text(m.done + '/' + m.total).fontSize(12).fontColor(C.textDim) }.width('100%') Progress({ value: m.done, total: m.total }).color(this.percent(m) === 100 ? C.ok : C.primary).width('100%') }.alignItems(HorizontalAlign.Start).layoutWeight(1) } .width('100%').padding(14).backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke }) }, (m: MemberProgress) => m.id.toString()) }.width('100%') }Progress线性条——与首页的ProgressType.Ring不同,进度页用默认线性条:
Progress({ value: m.done, total: m.total }) .color(this.percent(m) === 100 ? C.ok : C.primary) .width('100%')达标变色——percent(m) === 100时进度条变绿(C.ok),否则紫色(C.primary):
- 李班长 8/8 → 100% → 绿色进度条
- 王学委 5/6 → 83% → 紫色进度条
- 刘宣委 4/4 → 100% → 绿色进度条
100% 达标的成员进度条变绿——"完成"的视觉确认,与首页done === true的 ✅ 同语义。
卡片布局:44×44 浅紫圆头像 + 右侧双行(姓名 + done/total + Progress 条)。Progress宽度'100%'撑满右侧区域。
五、跨页数据自洽:进度页与首页的联动
- 28 总任务↔ 首页 4 条 + 其他未展示任务——进度页统计全量
- 22 已完成↔ 首页 doneCount(1 条已完成)+ 其他——进度页是全班级视角
- 79% 完成率= round(22/28*100) ↔ 我的页"83% 完成率"(5/6=83%,个人视角)
- 王学委 5/6↔ 我的页"完成 5 项任务"——当前登录用户是王学委
- 李班长 8/8 达标↔ 进度条变绿——100% 完成的视觉确认
六、可演进方向
| 方向 | 现状 | 改法 | 收益 |
|---|---|---|---|
| 数据来源 | 静态 5 人 | 从任务记录动态聚合 | 进度随任务更新 |
| 排序方式 | 数组顺序 | 按完成率倒序排序 | 高完成率在前 |
| 进度点击 | 无 onClick | 点击进入成员任务明细 | 下钻查看 |
| 达标激励 | 仅变色 | 100% 时显示勋章/徽章 | 达标成就感 |
| 时间维度 | 无 | 按周/月切换统计周期 | 时间趋势分析 |
进度页是班级任务的分析视角——OverallCard 三色概览 + MemberList 的Progress线性条 + 达标变色。从percent(m) === 100的条件变色到Math.round的百分比计算,每一层都有明确的职责边界。
系列导航:(一)首页 · (二)任务 ·(三)进度· (四)我的