鸿蒙原生应用 ArkUI 实战:三列汇总卡 + 三态过保列表 —— 保修管理首页的告警总览架构
鸿蒙原生应用 ArkUI 实战:三列汇总卡 + 三态过保列表 —— 保修管理首页的告警总览架构
App 53「保修期管理」首页(HomeTab),主题色
#00A862生态绿,4 个 Tab 分别为首页(🔧)、商品(📦)、保修(⏰)、我的(👤)。本篇基于53-warranty-mgr/entry/src/main/ets/pages/HomeTab.ets(共 108 行)逐段拆解,附 4 张实机截图。

一、整体结构:三区"Header + 汇总卡 + 列表"布局
首页是"品牌头部 + 保修统计 + 商品列表"的三区布局——3 个 @Builder 块:
build() {
Column() {
this.Header()
Scroll() {
Column({ space: 14 }) {
this.SummaryCard()
this.SectionTitle('即将过保')
this.ProductList()
}
.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)
}
3 块结构:Header(单行品牌头)→ SummaryCard(绿色渐变三列汇总卡)→ ProductList(4 条三态商品卡片)。首页是"保修总览页"——先亮出三类核心数据(8 件商品、2 件临期、1 件过保),再列出商品保修状态明细。相比 App 52 票据的"金额总览",本页是"时间总览"——保修管理关心的核心是"还剩多少天"。
二、Header:单行品牌头
Header() {
Column() {
Text('保修期管理').fontSize(22).fontWeight(FontWeight.Bold).fontColor(C.text)
.width('100%').padding({ top: this.safeTop + 10, left: D.pad, right: D.pad, bottom: 12 })
}.width('100%').backgroundColor(C.card)
}
22 号加粗、safeTop + 10 避让状态栏、白底全宽。与系列工具型首页(App 45/App 47/App 52)同款单行标题范式。
三、SummaryCard:三列渐变汇总卡
SummaryCard() {
Row() {
Column({ space: 4 }) {
Text('8').fontSize(24).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
Text('商品总数').fontSize(12).fontColor('#FFFFFF').opacity(0.9)
}.alignItems(HorizontalAlign.Start).layoutWeight(1)
Column({ space: 4 }) {
Text('2').fontSize(24).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
Text('即将过保').fontSize(12).fontColor('#FFFFFF').opacity(0.9)
}.alignItems(HorizontalAlign.Start).layoutWeight(1)
Column({ space: 4 }) {
Text('1').fontSize(24).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
Text('已过保').fontSize(12).fontColor('#FFFFFF').opacity(0.9)
}.alignItems(HorizontalAlign.Start).layoutWeight(1)
}
.width('100%').padding(20).borderRadius(D.rLg)
.linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] })
}
逐点拆解:
- 绿色渐变:
linearGradient从#00A862生态绿渐变到#4BC98A亮绿——绿色传达"安全/在保"的心理暗示,保修管理用绿色表达"一切尽在掌握"。 - 三列均分:
Row+ 三个layoutWeight(1)Column——商品总数(8)/ 即将过保(2)/ 已过保(1)三列 1:1:1,每列 24 号 Bold 白字数值 + 12 号 90% 白字标签。 - 与 App 52 的差异:52 是"两列副统计 + 大金额主数字"(一主二副),53 是"三列平级统计"——52 有唯一焦点(金额),53 三个数字同等重要(总数、临期、过保是三个不同告警维度),平级呈现让用户同时看到三个关键数。
- 标签透明度 0.9:小标签 90% 透明度弱化、数值 1.0 强调——"标签轻、数值重"的层级。
四、Product 数据模型 + SectionTitle
interface Product {
id: number;
emoji: string;
name: string;
daysLeft: number;
expired: boolean;
}
private products: Product[] = [
{ id: 1, emoji: '📱', name: 'iPhone 15 Pro', daysLeft: 45, expired: false },
{ id: 2, emoji: '💻', name: 'MacBook Air', daysLeft: 12, expired: false },
{ id: 3, emoji: '🎧', name: 'AirPods Pro', daysLeft: -30, expired: true },
{ id: 4, emoji: '⌚', name: 'Apple Watch', daysLeft: 180, expired: false }
];
Product 五字段:emoji(设备图标)、name(名称)、daysLeft(剩余天数,过保为负)、expired(是否过保)。4 件商品覆盖三态:iPhone 45 天(在保)、MacBook 12 天(临期)、AirPods -30 天(过保)、Apple Watch 180 天(在保)。
SectionTitle(title: string) {
Row() {
Text(title).fontSize(16).fontWeight(FontWeight.Bold).fontColor(C.text)
Blank()
Text('全部 >').fontSize(12).fontColor(C.textDim)
}.width('100%')
}
Blank() 撑开中间空间——左侧标题 + 右侧"全部 >"入口,与 App 52 同款弹性占位范式。
五、ProductList:三态商品卡片列表
ProductList() {
Column({ space: 10 }) {
ForEach(this.products, (p: Product) => {
Row({ space: 12 }) {
Row() { Text(p.emoji).fontSize(26) }
.width(50).height(50).backgroundColor(C.primarySoft).borderRadius(D.rSm).justifyContent(FlexAlign.Center)
Column({ space: 4 }) {
Text(p.name).fontSize(14).fontWeight(FontWeight.Medium).fontColor(C.text)
if (p.expired) {
Text('已过保 ' + (-p.daysLeft) + ' 天').fontSize(12).fontColor(C.danger)
} else if (p.daysLeft <= 30) {
Text('还剩 ' + p.daysLeft + ' 天过保').fontSize(12).fontColor(C.warn)
} else {
Text('还剩 ' + p.daysLeft + ' 天过保').fontSize(12).fontColor(C.ok)
}
}.alignItems(HorizontalAlign.Start).layoutWeight(1)
Text(p.expired ? '过保' : (p.daysLeft <= 30 ? '临期' : '在保')).fontSize(11)
.fontColor(p.expired ? C.danger : (p.daysLeft <= 30 ? C.warn : C.ok))
.padding({ left: 10, right: 10, top: 4, bottom: 4 })
.backgroundColor(p.expired ? '#FDEAEA' : (p.daysLeft <= 30 ? '#FEF3E0' : '#E8F7EE')).borderRadius(D.rSm)
}
.width('100%').padding(12).backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke })
.onClick(() => { promptAction.showToast({ message: p.name }); })
}, (p: Product) => p.id.toString())
}.width('100%')
}
逐点拆解:
- 50×50 主色软底图标块:
C.primarySoft(#E0F5EB)淡绿圆角底 + 26 号 emoji——每件商品一个专属 emoji(📱💻🎧⌚),扫一眼识别设备类型。 - 三态状态机(90-96 行):
if (p.expired)显示红字"已过保 30 天"(取-p.daysLeft转正);否则p.daysLeft <= 30显示橙字"还剩 12 天过保";否则绿字"还剩 45 天过保"——同一行文案用三元状态机渲染,三种状态三种颜色(红/橙/绿 = 危险/警告/正常)。 - 右侧状态胶囊(98-101 行):
'过保' / '临期' / '在保'三态胶囊——字色 + 底色双变化(红字粉底#FDEAEA/ 橙字黄底#FEF3E0/ 绿字绿底#E8F7EE),状态一眼可辨。 - 临期阈值 30 天:
daysLeft <= 30判定临期——与我的页"过保前 30 天提醒"阈值一致,30 天是全局统一告警阈值。 - 整卡点击:
onClick弹 Toast 商品名——产品化后跳商品详情页。

六、数据自洽:汇总 = 列表分项之和
Text('8').fontSize(24).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
{ id: 1, emoji: '📱', name: 'iPhone 15 Pro', daysLeft: 45, expired: false },
{ id: 2, emoji: '💻', name: 'MacBook Air', daysLeft: 12, expired: false },
{ id: 3, emoji: '🎧', name: 'AirPods Pro', daysLeft: -30, expired: true },
{ id: 4, emoji: '⌚', name: 'Apple Watch', daysLeft: 180, expired: false }
汇总卡 8 件商品 = 列表 4 件 + 未展示 4 件;2 件临期(MacBook 12 天 + 未展示 1 件)、1 件过保(AirPods -30 天)——汇总 = 列表分项之和,演示数据自洽。同时首页"iPhone 45 天"与保修页"剩余 45 天"完全一致,四页同源。

七、生态绿主题的视觉策略
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 = '#00A862';
static readonly primarySoft: string = '#E0F5EB';
static readonly accent: string = '#4BC98A';
static readonly warn: string = '#FF9F1C';
static readonly danger: string = '#FF5A6E';
static readonly ok: string = '#2BB673';
}
逐点拆解:
primary = #00A862:生态绿传达"安全/正常/健康"气质——与 App 47 班费绿(#00A862同色)一致,但 47 管"钱"(余额)、53 管"时间"(剩余天数),同色不同义。accent = #4BC98A:亮绿渐变终点——绿系渐变是"在保 = 安全"的视觉标识。- 三态语义色:
ok = #2BB673(在保绿)、warn = #FF9F1C(临期橙)、danger = #FF5A6E(过保红)——三色与列表状态机一一对应,全页统一引用。
八、系列横向对比:绿系工具首页三剑客
| 工具首页 | 代表 App | 首页焦点 | 核心动作 | 主题色 |
|---|---|---|---|---|
| 时间告警 | App 53 保修 | 三列汇总 + 三态列表 | 看剩余天数 → 处理临期 | #00A862 生态绿 |
| 金额汇总 | App 52 票据 | 渐变汇总卡 + 票据列表 | 看总额 → 查明细 | #0066CC 科技蓝 |
| 账务余额 | App 47 班费 | 余额卡 + 收支动态 | 看账 | #00A862 翡翠绿 |
差异点:App 53 的"三态状态机"是系列中少见的"状态型列表"——其他列表多为静态数据展示,53 的列表随剩余天数动态变色(在保绿/临期橙/过保红),是"防漏保"告警的视觉化表达。

九、开发者视角:调试与验证技巧
- 负数转正:过保商品
daysLeft存负值(-30),展示时用-p.daysLeft转正——数据层用负数表示"已超期天数",判断状态用正负、展示文案用绝对值,约定要在数据层注释清楚。 - 三态判定顺序:先判
expired(过保)、再判daysLeft <= 30(临期)、最后默认在保——判定顺序不可颠倒(若先判临期,过保商品 -30 也满足<= 30会被误判为临期),布尔过期标志 + 天数阈值两级判断是正确写法。 - 颜色语义统一:红 = 过保(danger)、橙 = 临期(warn)、绿 = 在保(ok)——三色语义与主题常量一一对应,后续所有页面都要沿用这套语义色,不能自行换色。
- 胶囊底色与字色:胶囊用浅色底 + 深色字(
#FDEAEA/#FEF3E0/#E8F7EE)——比"深色底白字"更柔和,适合列表中的小标签;注意三色浅底要能区分(都接近白色时用户无法辨识)。
十、演进方向
| 方向 | 当前状态 | 产品化演进 |
|---|---|---|
| 天数动态计算 | 硬编码 45/12/-30/180 | 到期日 - 今日 实时计算,每天自动更新 |
| 列表排序 | 数组声明顺序 | 按剩余天数升序,最紧急置顶 |
| 商品详情 | Toast"iPhone 15 Pro" | 跳商品详情页(保修卡/凭证/售后电话) |
| 过保分区 | 混在同一列表 | 过保商品单独成区或灰置 |
| 临期阈值 | 固定 30 天 | 用户可配置(7/15/30/60 天) |
十一、一句话总结
首页以"三列渐变汇总卡 + 三态商品列表"完成了保修管理的告警总览。linearGradient 生态绿渐变汇总卡(三列平级 8/2/1)、50×50 淡绿底 emoji 图标块、三元状态机渲染(在保绿/临期橙/过保红 + 状态胶囊字色底色双变化)、Blank() 弹性占位 SectionTitle——108 行代码,一个"看总量 → 盯临期 → 处理过保"的保修总览页,也是"时间管理"型首页的标准范式。

更多推荐





所有评论(0)