鸿蒙原生应用 HarmonyOS ArkTS:垃圾分类首页的四色入口与掌握度进度
鸿蒙原生应用 HarmonyOS ArkTS:垃圾分类首页的四色入口与掌握度进度
App 15「智能垃圾分类」首页(HomeTab),主题色
#22C55E绿色,4 个 Tab 分别为首页(♻️)、识别(📷)、分类(🗂️)、我的(👤)。首页采用固定 Header + 绿色渐变 HeroCard(本月减碳 + 3 栏统计 + 搜索框)+ 四色分类快捷入口(可回收蓝/有害红/厨余绿/其他灰)+ 本周分类趋势条形图 + 4 个分类指南卡片(星级/描述/掌握度进度条/学习入口/测试按钮)+ 识别排行。本篇基于15-trash-classify/entry/src/main/ets/pages/HomeTab.ets(约 318 行)逐段拆解,附 4 张实机截图。
一、整体结构:固定 Header + 内容流
HomeTab 与 App 14 首页骨架一致——固定 Header 在外、Scroll 内容流在内,7 个 @Builder 块:
build() {
Column() {
this.Header()
Scroll() {
Column({ space: 14 }) {
this.HeroCard()
this.QuickActionRow()
this.WeeklyChart()
this.SectionTitle('分类指南', '查看全部')
this.GuideList()
this.SectionTitle('识别排行', '更多')
this.RankList()
}
.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)
}
7 个块按"活动 → 入口 → 数据 → 指南 → 排行"五段叙事:HeroCard(减碳活动 + 3 栏统计 + 搜索)→ QuickActionRow(四色分类入口)→ WeeklyChart(本周趋势)→ SectionTitle('分类指南') + GuideList(4 个分类知识卡)→ SectionTitle('识别排行') + RankList(3 条排行)。
与 App 14 首页对比,本页是"知识型首页":主内容从"场地列表"换成"分类指南列表",每个分类卡带"掌握度进度条 + 学习/测试按钮"——App 14 是"预约行动",App 15 是"学习知识"。首页内容反映产品本质(App 14 是工具,App 15 是知识库)。

二、Header + HeroCard:减碳 Banner + 三栏统计 + 搜索
Header 与 App 14 同构(主标题"垃圾分类" + Slogan"智能识别,绿色生活从分类开始")。HeroCard 的"活动横幅"从"校运动会报名"换成了环保主题:
@Builder
HeroCard() {
Column({ space: 14 }) {
Row({ space: 12 }) {
Text('🌍').fontSize(36)
Column({ space: 4 }) {
Text('本月减碳 15.6kg').fontSize(16).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
Text('相当于种了 0.8 棵树').fontSize(12).fontColor('#FFFFFF').opacity(0.85)
}
.alignItems(HorizontalAlign.Start).layoutWeight(1)
Text('详情 >').fontSize(12).fontColor('#FFFFFF')
}
.width('100%')
.onClick(() => { promptAction.showToast({ message: '查看减碳详情' }); })
Row() {
ForEach(this.stats, (s: StatItem) => {
Column({ space: 4 }) {
Text(s.value).fontSize(22).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
Text(s.label).fontSize(11).fontColor('#FFFFFF').opacity(0.8)
}
.layoutWeight(1)
}, (s: StatItem) => s.label)
}
.width('100%')
Row({ space: 8 }) {
TextInput({ placeholder: '搜索垃圾名称...', text: this.keyword })
.onChange((val: string) => { this.keyword = val; })
.backgroundColor('#33FFFFFF').borderRadius(D.rSm).height(40)
.layoutWeight(1).placeholderColor('#FFFFFF').placeholderFont({ size: 13 })
.fontColor('#FFFFFF')
Text('🔍')
.fontSize(16).width(40).height(40).textAlign(TextAlign.Center)
.backgroundColor('#FFFFFF').borderRadius(D.rSm)
.onClick(() => {
promptAction.showToast({ message: this.keyword.length > 0 ? '搜索: ' + this.keyword : '请输入关键词' });
})
}
.width('100%')
}
.width('100%')
.padding(16)
.borderRadius(D.rLg)
.linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] })
}
"本月减碳 15.6kg / 相当于种了 0.8 棵树" 是环保类 App 的经典文案设计——把抽象数字翻译成具象场景(减碳 → 种树)。用户对"15.6kg"没概念,但对"0.8 棵树"有画面感。这种"数字具象化"文案在环保/健康/理财类 App 中被广泛使用(步数→卡路里、省钱→杯奶茶、减碳→种树)。
3 栏统计:本月分类 328 / 准确率 92% / 减碳量 15.6kg——与 App 14(预约/时长/卡路里)同为"量 → 质 → 果"三角,但 App 15 多了"准确率"(质量维度),体现"分类准不准"是用户关心的核心。
搜索框与 App 14 完全同构(半透明白底 + 白色占位 + 右侧白方块🔍),点击 Toast 反馈。

三、QuickActionRow:四色分类入口(本页特色)
QuickActionRow 是 4 个分类入口,每个入口带自己的主题色(这是与 App 14 最大的差异):
@Builder
QuickActionRow() {
Row() {
ForEach(this.quickActions, (q: QuickAction) => {
Column({ space: 6 }) {
Row() {
Text(q.emoji).fontSize(26)
}
.width(48).height(48)
.backgroundColor(q.color + '1A').borderRadius(24)
.justifyContent(FlexAlign.Center)
Text(q.label).fontSize(11).fontColor(C.textSub)
}
.layoutWeight(1)
.onClick(() => { promptAction.showToast({ message: q.label }); })
}, (q: QuickAction) => q.id.toString())
}
.width('100%')
.padding({ top: 14, bottom: 14 })
.backgroundColor(C.card).borderRadius(D.rMd)
.border({ width: 1, color: C.stroke })
}
4 个分类的颜色编码(数据自带 color 字段):
private quickActions: QuickAction[] = [
{ id: 1, emoji: '♻️', label: '可回收物', color: '#3B82F6' },
{ id: 2, emoji: '⚠️', label: '有害垃圾', color: '#EF4444' },
{ id: 3, emoji: '🍎', label: '厨余垃圾', color: '#22C55E' },
{ id: 4, emoji: '🗑️', label: '其他垃圾', color: '#9CA3AF' }
];
- 可回收物 → 蓝
#3B82F6(国际标准:可回收蓝桶) - 有害垃圾 → 红
#EF4444(危险警示红桶) - 厨余垃圾 → 绿
#22C55E(生态绿桶) - 其他垃圾 → 灰
#9CA3AF(中性灰桶)
颜色完全对标中国垃圾分类的"四色桶"国家标准(蓝红绿灰)——"颜色即知识",用户看入口颜色就记住分类标准。这是"主题色应用于数据语义"的典范。
背景色 q.color + '1A':用"颜色码 + 1A"拼出 10% 透明度的同色浅底(如 #3B82F61A 淡蓝)——比 App 14 的 C.primarySoft 单一浅绿更高级:每个分类的图标块是"自己的浅色",颜色层次更丰富。
borderRadius(24) 正圆图标块 + layoutWeight(1) 等分。点击弹 q.label("可回收物"等)——"轻反馈"策略。
四、WeeklyChart:本周分类趋势
WeeklyChart 与 App 14 完全同构(7 天条形图 + 平均 68%):
@Builder
WeeklyChart() {
Column({ space: 12 }) {
Row() {
Text('本周分类趋势').fontSize(15).fontWeight(FontWeight.Bold).fontColor(C.text)
Blank()
Text('平均 68%').fontSize(12).fontColor(C.primary)
}
.width('100%')
Row({ space: 4 }) {
ForEach(this.barData, (b: BarItem) => {
Column({ space: 6 }) {
Stack({ alignContent: Alignment.Bottom }) {
Column()
.width(18).height(b.value)
.linearGradient({ angle: 180, colors: [[C.primary, 0.0], [C.accent, 1.0]] })
.borderRadius(4)
}
.width(24).height(90)
Text(b.day).fontSize(10).fontColor(C.textDim)
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Center)
}, (b: BarItem) => b.day)
}
.width('100%')
}
.width('100%')
.padding(14)
.backgroundColor(C.card).borderRadius(D.rMd)
.border({ width: 1, color: C.stroke })
}
数据:一 50 / 二 70 / 三 45 / 四 85 / 五 60 / 六 90 / 日 75。周六 90 最高、周三 45 最低——周六(休息日)垃圾多、分类也多;周三(工作日)最少。"平均 68%" = (50+70+45+85+60+90+75)/7 ≈ 68,数据有数学依据。
Stack({ alignContent: Alignment.Bottom }) 柱子从底部"长"起来 + 渐变绿(C.primary → C.accent)——与 App 13/14 相同的"条形图三件套"。
五、SectionTitle + GuideList:4 个分类指南卡
GuideList 是首页的"知识主内容"——4 个分类卡,每个含 emoji 图标、名称、星级、描述、物品数、掌握度进度条、学习入口、测试按钮:
@Builder
GuideList() {
Column({ space: 12 }) {
ForEach(this.guides, (g: Guide) => {
Column({ space: 10 }) {
Row({ space: 12 }) {
Row() {
Text(g.emoji).fontSize(28)
}
.width(56).height(56)
.backgroundColor(g.color + '1A').borderRadius(D.rMd)
.justifyContent(FlexAlign.Center)
Column({ space: 4 }) {
Row({ space: 6 }) {
Text(g.name).fontSize(15).fontWeight(FontWeight.Medium).fontColor(C.text)
Row({ space: 1 }) {
ForEach([0, 1, 2, 3, 4], (i: number) => {
Text(i < g.rating ? '★' : '☆')
.fontSize(11).fontColor(i < g.rating ? C.warn : C.textDim)
}, (i: number) => i.toString())
}
}
.width('100%')
Text(g.desc).fontSize(12).fontColor(C.textDim)
}
.alignItems(HorizontalAlign.Start).layoutWeight(1)
Text(g.items).fontSize(11).fontColor(C.primary)
}
.width('100%')
Row({ space: 8 }) {
Text('掌握度').fontSize(11).fontColor(C.textDim)
Progress({ value: g.progress, total: 100 })
.color(g.color).backgroundColor(C.cardSoft)
.layoutWeight(1).height(6)
Text(g.progress + '%').fontSize(11).fontColor(C.textSub)
}
.width('100%')
Row() {
Text('点击学习 >').fontSize(11).fontColor(C.primary)
Blank()
Button('开始测试')
.fontSize(11).fontColor('#FFFFFF').backgroundColor(g.color)
.borderRadius(D.rSm).height(28)
.onClick(() => { promptAction.showToast({ message: g.name + ' 测试' }); })
}
.width('100%')
}
.width('100%')
.padding(14)
.backgroundColor(C.card).borderRadius(D.rMd)
.border({ width: 1, color: C.stroke })
.onClick(() => { promptAction.showToast({ message: g.name }); })
}, (g: Guide) => g.id.toString())
}
.width('100%')
}
5.1 4 个分类的数据设计
private guides: Guide[] = [
{ id: 1, emoji: '♻️', name: '可回收物', desc: '纸张、塑料、金属、玻璃等', items: '8 类物品', progress: 85, rating: 5, color: '#3B82F6' },
{ id: 2, emoji: '⚠️', name: '有害垃圾', desc: '电池、灯管、药品、油漆等', items: '6 类物品', progress: 60, rating: 4, color: '#EF4444' },
{ id: 3, emoji: '🍎', name: '厨余垃圾', desc: '剩饭剩菜、果皮、蛋壳等', items: '12 类物品', progress: 92, rating: 5, color: '#22C55E' },
{ id: 4, emoji: '🗑️', name: '其他垃圾', desc: '烟头、纸巾、陶瓷等', items: '5 类物品', progress: 45, rating: 3, color: '#9CA3AF' }
];
数据故事的讲究:
- 厨余垃圾 12 类物品、掌握度 92%、5 星——"最常接触、最熟悉"的分类(每天吃饭都产生)
- 可回收物 8 类、85%、5 星——"第二熟悉"
- 有害垃圾 6 类、60%、4 星——"少接触、略不熟"
- 其他垃圾 5 类、45%、3 星——"最不熟悉、最易混"
"掌握度"与"星级"的匹配:星级高(5★)对应掌握度高(85%/92%),星级低(3★)对应掌握度低(45%)——数据自洽。这种"掌握度低 → 引导学习"的设计,让用户一眼看出"我最该学的是其他垃圾"。
5.2 掌握度进度条(官方 Progress + 分类色)
Row({ space: 8 }) {
Text('掌握度').fontSize(11).fontColor(C.textDim)
Progress({ value: g.progress, total: 100 })
.color(g.color).backgroundColor(C.cardSoft)
.layoutWeight(1).height(6)
Text(g.progress + '%').fontSize(11).fontColor(C.textSub)
}
Progress 组件 + 每类自己的颜色(.color(g.color))——蓝色进度条(可回收)、红色(有害)、绿色(厨余)、灰色(其他)。进度条颜色与分类色一致,用户扫一眼颜色就能对号入座。"进度条 + 百分比数字"双通道(85% 数字 + 进度条),色弱用户也能读。
5.3 学习入口 + 测试按钮
Row() {
Text('点击学习 >').fontSize(11).fontColor(C.primary)
Blank()
Button('开始测试')
.fontSize(11).fontColor('#FFFFFF').backgroundColor(g.color)
.borderRadius(D.rSm).height(28)
.onClick(() => { promptAction.showToast({ message: g.name + ' 测试' }); })
}
"学习 → 测试"闭环:左侧"点击学习 >"入口(主色绿字)+ 右侧"开始测试"按钮(按钮颜色跟随分类色 .backgroundColor(g.color)——蓝色卡片的按钮是蓝色,红色卡片的按钮是红色)。按钮色跟随数据是"数据驱动 UI"的又一体现。
"学习 + 测试"是知识型 App 的标准双操作:先学再测、以测促学。整个分类指南卡 = "知识展示(描述/物品数)+ 进度追踪(掌握度)+ 行动入口(学习/测试)",功能完整。
六、RankList:识别排行
RankList 与 App 14 同构(3 条排行 + 奖牌 emoji + 次数 + 增长率):
@Builder
RankList() {
Column({ space: 10 }) {
ForEach(this.rankings, (r: RankItem) => {
Row({ space: 12 }) {
Text(r.emoji).fontSize(22)
Text(r.name).fontSize(14).fontColor(C.text).fontWeight(FontWeight.Medium).layoutWeight(1)
Column({ space: 2 }) {
Text(r.count).fontSize(12).fontColor(C.textSub)
Text(r.trend).fontSize(11).fontColor(C.ok)
}
.alignItems(HorizontalAlign.End)
}
.width('100%')
.padding({ left: 14, right: 14, top: 12, bottom: 12 })
.backgroundColor(C.card).borderRadius(D.rSm)
.border({ width: 1, color: C.stroke })
.onClick(() => { promptAction.showToast({ message: r.name }); })
}, (r: RankItem) => r.id.toString())
}
.width('100%')
}
3 条排行:🥇 厨余垃圾 156 次 +18% / 🥈 可回收物 98 次 +12% / 🥉 其他垃圾 74 次 +6%。
"识别次数排行"与"掌握度"的呼应:厨余垃圾识别最多(156 次)且掌握度最高(92%)——"用得越多越熟";其他垃圾识别最少(74 次)且掌握度最低(45%)——"用得越少越生疏"。排行与指南的数据互相印证,首页的"数据故事"自洽完整。
与 App 14 的差异:App 14 排行是"场地预约次数",App 15 是"垃圾识别次数"——排行对象反映业务类型。
七、四色系统的设计价值
App 15 首页最值得学习的是**"四色分类系统"**——同一个颜色码贯穿全页:
| 颜色 | 分类 | 出现位置 |
|---|---|---|
| 蓝 #3B82F6 | 可回收物 | 快捷入口图标块、指南图标块、掌握度进度条、测试按钮 |
| 红 #EF4444 | 有害垃圾 | 同上 |
| 绿 #22C55E | 厨余垃圾 | 同上 |
| 灰 #9CA3AF | 其他垃圾 | 同上 |
一个分类一个颜色,全页 4 处复用(入口/图标/进度条/按钮)。用户只需记住"蓝=可回收、红=有害、绿=厨余、灰=其他",整页信息自动关联。"颜色即语义"是数据可视化的最高境界——比"给每张卡单独配随机颜色"高级得多。
实现方式:Guide 接口带 color: string 字段,数据驱动渲染(g.color + '1A' 背景、.color(g.color) 进度条、.backgroundColor(g.color) 按钮)。"颜色进数据"让 UI 代码零分支——没有 if (name === '可回收') color = blue 这种硬编码,加新分类只需加一条数据。
八、与 App 14 首页的对比总结
| 维度 | App 14 运动预约首页 | App 15 垃圾分类首页 |
|---|---|---|
| 主题色 | 绿 #16A34A | 绿 #22C55E |
| Hero 活动 | 校运动会报名 | 本月减碳种树 |
| 快捷入口 | 4 个运动(同色) | 4 个分类(四色) |
| 主列表 | 场地(星级+进度+预约) | 指南(星级+掌握度+学习/测试) |
| 排行榜 | 场地预约排行 | 垃圾识别排行 |
| 特色机制 | 预约进度条 | 四色编码 + 学习测试闭环 |
同一套"内容流首页"模板,第三次复用(App 13 音乐/14 运动/15 环保),每次换主题、换数据、换模块——"模板复用 + 主题演化"是系列化 demo 的核心方法论。

九、知识型首页的设计要点
App 15 首页是系列第一个"知识型首页",几个值得沉淀的设计原则:
- "学测闭环":每个知识卡都有"学习 + 测试"双操作,用户从"看"到"练"一步到位
- "掌握度"可视化:进度条 + 百分比让用户知道"自己会多少",有成长感
- "低掌握度引导":其他垃圾 45% 掌握度最低 → 用户自然想去学它——"数据引导行动"(比"随机推荐"高级)
- "数字具象化":"减碳 15.6kg = 种 0.8 棵树"让环保成果可感知,激励用户持续使用
这套"知识卡片 + 掌握度 + 学测闭环"模板可复用到:背单词(单词卡+掌握度+测试)、学英语、学习强国、驾考宝典、刷题类 App——任何"知识学习"场景。

十、扩展建议
首页的搜索框目前只弹 Toast,真实项目应联动 GuideList:
// 伪代码:搜索过滤指南
private filteredGuides(): Guide[] {
if (this.keyword.trim() === '') return this.guides;
return this.guides.filter(g => g.name.includes(this.keyword.trim()) || g.desc.includes(this.keyword.trim()));
}
"点击学习 >"应跳转到分类详情页(显示该分类的全部物品清单);"开始测试"应进入测验页(选择题模式);排行应支持"日/周/月"切换。每一个"伪交互"都是一个真实功能的占位——demo 的每一处 Toast 都值得在真实项目中"落地"。
十一、环保主题的视觉与文案设计
App 15 首页在"主题一致性"上做得非常彻底,值得总结 3 个手法:
1. 文案的系统性。首页文案全部围绕"环保"展开:Slogan"智能识别,绿色生活从分类开始"、Hero 活动"本月减碳 15.6kg/相当于种了 0.8 棵树"、统计标签"本月分类/准确率/减碳量"、指南卡"掌握度/点击学习/开始测试"、排行"识别次数/增长率"——没有一个词跳出环保语境。如果 Slogan 是"智能分类,高效便捷"就违和了。"文案即主题"是主题一致性的第一层。
2. 视觉的系统性。绿色主色(#22C55E)贯穿:Header、HeroCard 渐变、趋势图柱子、按钮、Tab 高亮——"主色全页复用"。四色编码(蓝红绿灰)作为"业务色"补充:分类入口、指南卡、进度条、按钮——"业务色按分类复用"。**"主色表达品牌,业务色表达语义"**是双色系统的正确姿势。
3. 图标的系统性。♻️(可回收)⚠️(有害)🍎(厨余)🗑️(其他)——4 个分类的 emoji 是全 App 统一约定(首页入口、指南卡、识别页选择器、分类页记录都用同一套)。用户在首页记住"🍎=厨余",识别页看到 🍎 自动关联。"跨页图标一致"是主题一致性的第三层。
三层一致性(文案/视觉/图标)叠加,让 App 15 的"环保感"深入骨髓——比只换主题色高级得多。

十二、学习路径设计:从"看"到"练"
App 15 首页的"分类指南"隐含了一条学习路径设计:
浏览首页(看趋势、看排行,建立"我在用"的感觉)
→ 点开分类指南(看描述、看物品数,建立"我该学什么"的认知)
→ 点击学习(进入知识详情,建立"我学会了"的体验)
→ 开始测试(验证掌握度,建立"我会了"的成就感)
→ 掌握度提升(进度条 45% → 60% → 85%,可视化成长)
"浏览 → 认知 → 学习 → 测试 → 成长"五步闭环,每一步都有 UI 载体(趋势图/指南卡/学习入口/测试按钮/掌握度进度条)。"学习路径"是知识型产品(学习类 App、驾考类 App、理财课程类 App)的核心设计——比"把所有内容堆在首页"高级得多。
掌握度进度条是这条路径的"进度反馈":其他垃圾 45% 最低 → 用户最想学它 → 学完测试 → 掌握度涨 → 成就感。"低掌握度引导学习"是数据驱动的个性化推荐(不靠算法,靠 UI 呈现让用户自己发现)。
真实项目可加"学习提醒":掌握度 < 60% 的分类,首页显示"该分类有待学习内容"红点;学完测试通过,解锁"知识百科"成就(与我的页成就墙联动)——"首页引导 → 学习页完成 → 成就页激励"的三页闭环。
十三、首页可复用模板总结
App 15 首页模板:
固定 Header(标题 + 环保 Slogan)
Scroll(
HeroCard(减碳活动 + 3 栏统计 + 搜索框)+
QuickActionRow(四色分类入口)+
WeeklyChart(本周趋势 + 平均值)+
SectionTitle('分类指南') + GuideList(四色指南卡 + 掌握度 + 学测)+
SectionTitle('识别排行') + RankList(3 条排行)
)
与 App 14 首页模板对比:完全同构(7 块),差异只在"数据语义"(场地→指南、预约→掌握度、排行对象)。"内容流首页"模板已稳定复用 3 次(App 13/14/15)——这是系列化 demo 最核心的资产:一套模板 + 主题数据 = 无限应用。
十四、小结
App 15 首页解析完毕。四色编码系统 + 掌握度可视化 + 学测闭环 + 三层主题一致性是四大亮点,配合绿色环保主题(减碳/种树/分类),让这个首页既是"视觉示范"又是"知识产品"。
更多推荐




所有评论(0)