鸿蒙原生应用 ArkUI 实战:渐变用户卡 + 负边距统计 + 提醒开关 —— 我的页的个人中心与提醒中枢架构
鸿蒙原生应用 ArkUI 实战:渐变用户卡 + 负边距统计 + 提醒开关 —— 我的页的个人中心与提醒中枢架构
App 53「保修期管理」我的页(ProfileTab),主题色
#00A862生态绿,4 个 Tab 分别为首页(🔧)、商品(📦)、保修(⏰)、我的(👤)。本篇基于53-warranty-mgr/entry/src/main/ets/pages/ProfileTab.ets(共 114 行)逐段拆解,附 4 张实机截图。

一、整体结构:五区"用户卡 + 统计 + 开关 + 菜单 + 版本"布局
我的页是"个人中心 + 提醒设置 + 工具入口"的五区布局——5 个 @Builder 块:
build() {
Column() {
Scroll() {
Column() {
this.UserCard()
this.StatRow()
this.RemindCard()
this.MenuList()
this.About()
}
.width('100%')
.padding({ bottom: D.pad + this.safeBottom + 20 })
}
.layoutWeight(1).scrollBar(BarState.Off).align(Alignment.Top)
}
.width('100%').height('100%').backgroundColor(C.bg)
}
5 块结构:UserCard(渐变用户卡)→ StatRow(负边距统计行)→ RemindCard(提醒开关卡)→ MenuList(四菜单)→ About(版本号)。相比 App 52 票据的个人中心(身份 → 数据 → 菜单),本页多了一个"提醒开关"区——提醒是保修管理应用的核心能力(漏过保 = 损失),开关卡是页面功能性的体现。
二、数据模型:统计与菜单
interface StatItem { value: string; label: string; }
interface MenuItem { id: number; emoji: string; title: string; }
private stats: StatItem[] = [
{ value: '8', label: '商品档案' },
{ value: '2', label: '临期提醒' },
{ value: '15', label: '历史记录' }
];
private menus: MenuItem[] = [
{ id: 1, emoji: '📦', title: '商品档案' },
{ id: 2, emoji: '⏰', title: '保修提醒' },
{ id: 3, emoji: '📋', title: '历史记录' },
{ id: 4, emoji: '⚙️', title: '设置' }
];
StatItem 两字段(值 + 标签)、MenuItem 三字段(id + emoji + 标题)。3 项统计(8 档案 / 2 临期 / 15 历史)+ 4 项菜单(档案/提醒/历史/设置)。8 = 首页"8 商品总数"、2 = 首页"2 即将过保"——我的页统计与首页汇总完全一致。
三、UserCard:绿色渐变用户卡
UserCard() {
Row({ space: 14 }) {
Row() { Text('🔧').fontSize(32) }
.width(64).height(64).backgroundColor('#33FFFFFF').borderRadius(32).justifyContent(FlexAlign.Center)
Column({ space: 5 }) {
Text('保修管家').fontSize(18).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
Text('管理 8 件商品保修').fontSize(12).fontColor('#FFFFFF').opacity(0.85)
}.alignItems(HorizontalAlign.Start).layoutWeight(1)
}
.width('100%')
.padding({ top: this.safeTop + 30, left: D.pad, right: D.pad, bottom: 44 })
.linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] })
}
逐点拆解:
- 绿色渐变背景:
linearGradient从#00A862渐变到#4BC98A——与首页汇总卡、App 52 用户卡同款渐变手法,品牌视觉统一。 - 64×64 半透明圆头像:
backgroundColor('#33FFFFFF')——白色 20% 透明度圆角 32 头像底,🔧 32 号居中。"🔧"(扳手)即产品符号(与 Tab 图标一致),保修 = 维修 = 扳手的符号联想。 - 身份 + 副文案:18 号 Bold 白字"保修管家" + 12 号 85% 白字"管理 8 件商品保修"——8 件商品是用户卡的背书数据(与首页"8 商品总数"一致)。
- 底部留白 44:
bottom: 44+safeTop + 30——顶部避让、底部大留白(给负边距统计行让位),与 App 52 完全同款。
四、StatRow:负边距三列统计行
StatRow() {
Row() {
ForEach(this.stats, (s: StatItem) => {
Column({ space: 4 }) {
Text(s.value).fontSize(18).fontWeight(FontWeight.Bold).fontColor(C.text)
Text(s.label).fontSize(11).fontColor(C.textDim)
}.layoutWeight(1)
}, (s: StatItem) => s.label)
}
.width('92%').padding({ top: 14, bottom: 14 })
.backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke }).margin({ top: -24 })
}
逐点拆解:
- 负边距悬浮:
.margin({ top: -24 })——统计行上移 24 覆盖在渐变卡留白区(系列经典悬浮手法,App 52 同款),"卡片叠卡"的层次感。 - 三列均分:
layoutWeight(1)三列——8(商品档案)/ 2(临期提醒)/ 15(历史记录),每列 18 号 Bold 数值 + 11 号淡灰标签。 - 数据一致性:8 = 首页"8 商品总数"、2 = 首页"2 即将过保"——同一批数据两个视角。
- 15 历史记录:第三列是操作流水(维修/查询累计 15 次),与"8 档案、2 提醒"是不同维度(档案是存量、提醒是告警、历史是流水)。
五、RemindCard:过保提醒开关卡
RemindCard() {
Row() {
Column({ space: 2 }) {
Text('过保提醒').fontSize(14).fontColor(C.text)
Text('过保前 30 天提醒').fontSize(11).fontColor(C.textDim)
}.alignItems(HorizontalAlign.Start).layoutWeight(1)
Toggle({ type: ToggleType.Switch, isOn: this.remindOn })
.selectedColor(C.primary)
.onChange((v: boolean) => { this.remindOn = v; })
}
.width('92%').padding(16).margin({ top: 14 }).backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke })
}
逐点拆解:
- 开关设置卡:左侧"过保提醒"14 号 + "过保前 30 天提醒"11 号淡灰副文案,右侧
Toggle({ type: ToggleType.Switch, isOn: this.remindOn })——开关卡是"设置"的最小形态(一句话说明 + 一个开关)。 - 选中色主绿:
.selectedColor(C.primary)——开关开启时轨道变#00A862生态绿,开关状态与主题色关联(开启 = 主题绿 = 安全)。 - 状态双向绑定:
isOn: this.remindOn+onChange((v) => { this.remindOn = v; })——开关状态持久化在 @State(当前仅内存态,产品化需 Preferences 存储)。 - 30 天阈值:副文案"过保前 30 天提醒"——与首页临期判定(
daysLeft <= 30)阈值一致,开关开启后临期商品会收到提醒,"列表标临期 = 会提醒"的一致性闭环。 - 本页独有功能:这是系列个人中心中首个带功能性开关的页面——App 52 票据我的页只有静态菜单,53 增加了"过保提醒"开关,体现保修管理"主动告警"的产品特性。
六、MenuList:四工具菜单列表
MenuList() {
Column() {
ForEach(this.menus, (m: MenuItem, idx: number) => {
Row({ space: 12 }) {
Text(m.emoji).fontSize(18)
Text(m.title).fontSize(14).fontColor(C.text).layoutWeight(1)
Text('>').fontSize(14).fontColor(C.textDim)
}
.width('100%').padding({ left: 14, right: 14, top: 14, bottom: 14 })
.onClick(() => { promptAction.showToast({ message: m.title }); })
if (idx < this.menus.length - 1) { Divider().color(C.stroke).strokeWidth(0.5) }
}, (m: MenuItem) => m.title)
}
.width('92%').margin({ top: 14 }).backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke })
}
逐点拆解:
- 左 emoji + 中标题 + 右箭头:18 号 emoji(📦⏰📋⚙️)+ 14 号标题 + 14 号
>箭头——标准列表行,右箭头暗示"可进入"。 - 0.5 细 Divider:
idx < length - 1判断后插入——最后一项不画线,整宽细线分隔(与 App 52 同款)。 - 整行点击:点击 Toast 菜单名——产品化后跳对应功能页(商品档案 ↔ 首页列表、保修提醒 ↔ RemindCard 设置页)。
- 4 菜单 vs 5 菜单:App 52 有 5 个菜单(多"导出报销单/云端备份"),53 精简为 4 个——菜单数量与产品能力匹配(保修场景能力更聚焦)。

七、About:底部版本信息
About() {
Column({ space: 4 }) {
Text('保修期管理').fontSize(12).fontColor(C.textDim)
Text('Version 1.0.0').fontSize(11).fontColor(C.textDim).opacity(0.7)
}.width('100%').margin({ top: 24 })
}
12 号淡灰"保修期管理" + 11 号 70% 透明"Version 1.0.0"——应用名 + 版本号,个人中心标准收尾(App 52 同款 About 区)。

八、跨页数据自洽:个人中心的全局闭环
{ value: '8', label: '商品档案' },
Text('8').fontSize(24).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
我的页"8 商品档案 / 2 临期提醒"与首页"8 商品总数 / 2 即将过保"完全一致——同一批数据两个视角。我的页"过保前 30 天提醒"与首页"临期"判定(daysLeft <= 30)共用同一阈值——开关开启后临期商品(MacBook 12 天)触发提醒,"列表标临期 = 收到提醒"的规则闭环。

九、系列横向对比:个人中心两种风格
| 个人中心 | 代表 App | 核心特色 | 差异点 | 主题色 |
|---|---|---|---|---|
| 提醒开关型 | App 53 保修 | 渐变卡 + 统计 + 开关 + 四菜单 | 功能性开关 | #00A862 生态绿 |
| 财务导出型 | App 52 票据 | 渐变卡 + 统计 + 五菜单 | 导出报销 | #0066CC 科技蓝 |
差异点:App 53 的"提醒开关"是系列个人中心中首个功能性开关组件(其他个人中心均为纯展示/导航),它把"提醒设置"从深层设置页提升到首屏,符合保修管理"主动告警"的核心价值。统计行的"临期提醒 2"与开关形成呼应——数据告诉你 2 件临期、开关决定要不要提醒,数据 + 操作在同一屏联动。
十、开发者视角:调试与验证技巧
- Toggle 状态持久化:
remindOn是 @State 内存态——应用重启后开关会复位(产品化需用 Preferences 持久化存储保存开关状态,并在页面加载时读取)。这是所有"设置开关"的通用坑。 - 开关与提醒逻辑联动:当前开关只改变自身状态——产品化需联动通知权限(开启提醒要先申请通知权限,未授权时应引导跳设置页),开关状态 ≠ 实际提醒能力。
- 负边距与留白配合:统计行
-24与用户卡bottom: 44——负边距值必须小于留白值(44 > 24),否则统计行会遮住身份文字;调整任一值时需同步验证叠卡效果。 - 菜单数量与页面长度:5 区结构在小屏设备可能超出首屏——当前 Scroll 包裹保证可滚动,但菜单项增加时应考虑"统计区 + 开关区"是否压缩。
十一、演进方向
| 方向 | 当前状态 | 产品化演进 |
|---|---|---|
| 开关持久化 | @State 内存态 | Preferences 存储,重启后保持 |
| 通知权限 | 无 | 申请通知权限 + 引导跳设置页 |
| 临期阈值 | 固定 30 天 | 用户可配置(7/15/30/60 天) |
| 提醒推送 | 无 | 临期商品推送通知 + 定时检查 |
| 菜单跳转 | Toast 菜单名 | 跳对应功能页(档案/提醒/历史/设置) |
十二、一句话总结
我的页以"渐变用户卡 + 负边距统计 + 提醒开关 + 四菜单"完成了个人中心与提醒中枢的构建。linearGradient 生态绿渐变用户卡(64×64 半透明圆头像 + 8 件商品背书)、margin({ top: -24 }) 负边距悬浮统计行(三列 8/2/15)、Toggle Switch 开关(selectedColor 主绿 + 30 天阈值与首页联动)、0.5 细 Divider 四菜单列表——114 行代码,一个"看身份 → 看统计 → 设提醒 → 进工具"的个人中心页,也是"提醒开关型"个人中心的标准范式。

更多推荐





所有评论(0)