HarmonyOS 应用 · 班级任务首页深度解析:Progress 环形进度与 toggle 勾选刷新

项目编号:48-class-task 技术栈:HarmonyOS ArkTS · ArkUI 声明式 UI · Stage 模型 本篇页面:首页 HomeTab.ets(103 行) 系列导航:(一)首页 · (二)任务 · (三)进度 · (四)我的

48 首页首屏


一、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 勾选态同步更新。

48 首页完整列表

48 首页勾选任务

48 首页取消勾选


七、可演进方向

方向现状改法收益
任务创建静态 4 条接入任务 Tab 创建后追加任务动态新增
数据持久@State 内存Preferences 持久化重启不丢失
过期检测无比对 deadline 与当前日期过期任务标红
拖拽排序无ItemTouchHelper 拖拽任务优先级手动调整
任务详情无 onClick点击进入详情页展示完整描述

首页是班级任务的概览——ProgressCard 的环形进度 + TaskList 的 done 驱动勾选双态。从 toggle 的不可变更新到 TextDecorationType.LineThrough 的删除线装饰,每一层都有明确的职责边界。

系列导航:(一)首页 · (二)任务 · (三)进度 · (四)我的

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐