鸿蒙原生应用 ArkUI 实战:渐变用户卡 + 负边距统计 + 推送开关 —— 续费提醒我的页的通知中枢架构
鸿蒙原生应用 ArkUI 实战:渐变用户卡 + 负边距统计 + 推送开关 —— 续费提醒我的页的通知中枢架构
App 55「自动续费提醒」我的页(ProfileTab),主题色
#FF6B6B珊瑚红,4 个 Tab 分别为首页(⏰)、添加(➕)、日历(�)、我的(👤)。本篇基于55-renewal-reminder/entry/src/main/ets/pages/ProfileTab.ets(共 114 行)逐段拆解,附 4 张实机截图。

一、整体结构:五区"用户卡 + 统计 + 开关 + 菜单 + 版本"布局
我的页是"个人中心 + 通知设置 + 工具入口"的五区布局——5 个 @Builder 块:
build() {
Column() {
Scroll() {
Column() {
this.UserCard()
this.StatRow()
this.PushCard()
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(负边距统计行)→ PushCard(推送通知开关)→ MenuList(四菜单)→ About(版本号)。与 App 53 我的页结构完全同构(卡/统计/开关/菜单/版本),但开关语义不同——53 是"过保提醒"、55 是"推送通知"。提醒类应用的我的页,开关卡是标配。
二、数据模型 + 状态声明
interface StatItem { value: string; label: string; }
interface MenuItem { id: number; emoji: string; title: string; }
@State pushOn: boolean = true;
private stats: StatItem[] = [
{ value: '5', label: '提醒项目' },
{ value: '¥746', label: '年度支出' },
{ value: '12', label: '历史记录' }
];
private menus: MenuItem[] = [
{ id: 1, emoji: '📋', title: '提醒规则' },
{ id: 2, emoji: '🕐', title: '历史记录' },
{ id: 3, emoji: '🏷️', title: '分类管理' },
{ id: 4, emoji: '⚙️', title: '设置' }
];
@State pushOn 默认 true(推送默认开启——提醒类应用的核心能力就是推送,默认开)。3 项统计(5 提醒项目 / ¥746 年度支出 / 12 历史记录)+ 4 项菜单(提醒规则/历史记录/分类管理/设置)。5 与 ¥746 与日历页完全一致——同一批数据的全局复用。
三、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('管理 5 个续费提醒').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从#FF6B6B渐变到#FFB0B0——与首页告警卡同款渐变,品牌视觉统一。 - 64×64 半透明圆头像:
backgroundColor('#33FFFFFF')白色 20% 透明 + ⏰ 32 号居中——⏰ 是产品符号(与首页告警卡图标、Tab 图标一致),提醒 = 闹钟的符号联想。 - 身份 + 数据背书:18 号 Bold"续费管家" + 12 号 85% 透明"管理 5 个续费提醒"——5 项与日历页"5 续费项目"一致。
- 底部留白 44:
bottom: 44给负边距统计行让位——系列同款叠卡手法(App 52/53 均用)。
四、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 覆盖在渐变卡留白区,"卡片叠卡"层次感(系列经典手法)。 - 三列均分:5 提醒项目 / ¥746 年度支出 / 12 历史记录——18 号 Bold 数值 + 11 号淡灰标签。
- 数据一致性:5 = 日历页"5 续费项目"、¥746 = 日历页"¥746 年度总额"——三页同源(首页近期 4 项是 5 项的子集)。
五、PushCard:推送通知开关卡
PushCard() {
Row() {
Column({ space: 2 }) {
Text('推送通知').fontSize(14).fontColor(C.text)
Text('扣款前推送提醒').fontSize(11).fontColor(C.textDim)
}.alignItems(HorizontalAlign.Start).layoutWeight(1)
Toggle({ type: ToggleType.Switch, isOn: this.pushOn })
.selectedColor(C.primary)
.onChange((v: boolean) => { this.pushOn = v; })
}
.width('92%').padding(16).margin({ top: 14 }).backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke })
}
逐点拆解:
- 开关卡结构:左侧"推送通知"14 号 + "扣款前推送提醒"11 号淡灰副文案,右侧 Switch——与 App 53 我的页开关卡完全同构(文案 +
layoutWeight(1)+ Toggle)。 - 选中色主题红:
.selectedColor(C.primary)——开关开启时轨道变珊瑚红,与 App 53 的绿色开关、App 54 的紫色开关形成"开关颜色 = 主题色"的系列约定。 - 默认开启:
pushOn = true——提醒类应用的推送是核心价值,默认开(用户装这个 App 就是为了被提醒)。 - 双向绑定:
isOn: this.pushOn+onChange回写——@State 内存态,产品化需 Preferences 持久化 + 通知权限联动。
六、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 })
}
逐点拆解:
- 标准列表行:18 号 emoji + 14 号标题
layoutWeight(1)+ 14 号>箭头——系列同款范式。 - 条件 Divider:
idx < length - 1时才画 0.5 细线——最后一项不画线,列表底部干净。 - 菜单语义:📋 提醒规则(编辑提前天数/周期)、🕐 历史记录(12 条操作流水)、🏷️ 分类管理(订阅分类维护)、⚙️ 设置——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% 透明版本号——系列标准收尾(App 52/53 同款 About 区)。

八、跨页数据自洽:个人中心的全局闭环
{ value: '5', label: '提醒项目' },
{ value: '¥746', label: '年度支出' },
Text('¥746').fontSize(22).fontWeight(FontWeight.Bold).fontColor(C.primary)
...
Text('5').fontSize(22).fontWeight(FontWeight.Bold).fontColor(C.accent)
- 我的页"5 提醒项目 / ¥746 年度支出" ↔ 日历页"5 续费项目 / ¥746 年度总额"——数字完全一致,统计与日历展示同一批数据。
- 我的页"推送通知"开关 ↔ 添加页"提前提醒 1/3/7 天"——开关是"要不要推"的总闸,添加页的天数是"提前多久推"的参数,开关 × 天数共同决定推送行为。
- 菜单"提醒规则" ↔ 添加页 RemindCard——规则菜单是提醒设置的进阶管理页,添加页的胶囊是录入时的单次选择。
- 菜单"历史记录 12 条" ↔ 用户操作流水——添加提醒、开关切换、查看日历各记一笔。

九、系列横向对比:开关型我的页双生花
| 我的页 | 代表 App | 开关语义 | 默认状态 | 主题色 |
|---|---|---|---|---|
| 推送开关 | App 55 续费 | 扣款前推送提醒 | 开(提醒是核心价值) | #FF6B6B 珊瑚红 |
| 提醒开关 | App 53 保修 | 过保前 30 天提醒 | 开 | #00A862 生态绿 |
差异点:App 53 与 55 的我的页结构完全同构(渐变卡 + 负边距统计 + 开关卡 + 四菜单 + 版本),但开关的语义层级不同——53 的开关管"要不要提醒"(业务规则),55 的开关管"要不要推送"(系统通道)。55 的开关更底层:关掉推送 = 整个 App 失声;53 关掉提醒只是不再主动提示,数据还在。同构骨架承载不同权重的开关,是系列"骨架统一、语义各异"方法论的体现。
十、开发者视角:调试与验证技巧
- Toggle 持久化:
pushOn是 @State 内存态——重启复位,产品化需 Preferences 存储;且推送开关必须与系统通知权限状态同步(系统关权限时 App 内开关应置灰并引导跳设置)。 - 负边距联动:统计行
-24与用户卡bottom: 44——负边距值必须小于留白值,改任一值需同步验证叠卡效果(与 App 53 同款约束)。 - 92% 宽度体系:StatRow/PushCard/MenuList 均
width('92%')——三卡同宽居中悬浮,与用户卡全宽形成"全宽底卡 + 悬浮子卡"的层次;新增区块需沿用 92% 保持对齐。 - 菜单与统计的呼应:统计行"历史记录 12"与菜单"🕐 历史记录"同义重复——统计给数量、菜单给入口,产品化时点击统计数字也可跳对应页,双入口提升可达性。
十一、演进方向
| 方向 | 当前状态 | 产品化演进 |
|---|---|---|
| 开关持久化 | @State 内存态 | Preferences 存储 + 重启恢复 |
| 权限联动 | 无 | 系统通知权限检测 + 未授权引导 |
| 统计点击 | 无 | 统计数字跳对应页(提醒项目→列表) |
| 提醒规则页 | Toast 占位 | 全局默认提醒天数 + 单项覆盖规则 |
| 推送通道 | 无 | 对接系统推送服务,定时任务检查扣款日 |
十二、一句话总结
我的页以"红色渐变用户卡 + 负边距统计 + 推送开关 + 四菜单"完成了续费提醒的个人中心。linearGradient 珊瑚红渐变用户卡(⏰ 符号 + 5 项背书)、margin({ top: -24 }) 悬浮统计行(5/¥746/12 与日历页同源)、Toggle 开关 selectedColor(C.primary) 红色选中态(默认开 + 推送语义)、0.5 细 Divider 四菜单——114 行代码,一个"亮身份 → 看总账 → 管推送 → 进工具"的个人中心页,也是"提醒类应用开关卡"的标准范式。

更多推荐





所有评论(0)