鸿蒙原生应用 ArkUI 实战:渐变 UserCard + 负 margin 悬浮 —— 票据我的页的个人中心架构
鸿蒙原生应用 ArkUI 实战:渐变 UserCard + 负 margin 悬浮 —— 票据我的页的个人中心架构
App 52「电子票据管理」我的页(ProfileTab),主题色
#0066CC科技蓝,4 个 Tab 分别为首页(🧾)、上传(📤)、分类(📂)、我的(👤)。本篇基于52-e-receipt/entry/src/main/ets/pages/ProfileTab.ets(共 99 行)逐段拆解,附 4 张实机截图。

一、整体结构:四区"用户卡 + 统计行 + 菜单 + 版本"布局
我的页是"个人中心 + 工具入口"的四区布局——4 个 @Builder 块:
build() {
Column() {
Scroll() {
Column() {
this.UserCard()
this.StatRow()
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)
}
4 块结构:UserCard(蓝色渐变用户卡)→ StatRow(负边距三列统计行)→ MenuList(5 行菜单)→ About(版本收尾)。与 App 45-51 我的页同构的"头图 + 悬浮卡 + 菜单 + 版本"范式。
二、数据模型:统计 + 菜单
interface StatItem { value: string; label: string; }
interface MenuItem { id: number; emoji: string; title: string; }
private stats: StatItem[] = [
{ value: '48', label: '票据总数' },
{ value: '¥6.6k', label: '总金额' },
{ value: '12', label: '导出记录' }
];
private menus: MenuItem[] = [
{ id: 1, emoji: '🔍', title: '票据搜索' },
{ id: 2, emoji: '📊', title: '消费统计' },
{ id: 3, emoji: '⬆️', title: '导出报销单' },
{ id: 4, emoji: '☁️', title: '云端备份' },
{ id: 5, emoji: '⚙️', title: '设置' }
];
stats 三项:48 票据总数 / ¥6.6k 总金额 / 12 导出记录——制作量 + 总金额 + 导出量是财务工具的数据模型。menus 5 项含"⬆️ 导出报销单"——财务场景独有的报销功能入口。
三、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('管理 48 张票据 · 6600元').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从#0066CC渐变到#4D99E0——与首页汇总卡同款渐变,品牌统一。 - 🧾 64×64 半透明圆头像:
#33FFFFFF(白色 20% 透明度)圆角 32——🧾 票据 emoji 即产品符号(与 Tab 图标一致)。 - "票据管家" + 副文案:18 号 Bold 白字 + 12 号 85% "管理 48 张票据 · 6600元"——身份名大、数据副行小,48 张/6600 元是用户卡的点睛数据。
- 底部 44 padding:为负边距统计行预留悬浮空间。
四、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 覆盖在渐变卡留白区——系列标志性"悬浮卡片"手法,制造"卡片叠卡"层次感。 - 三列均分:
layoutWeight(1)三列——48(票据总数)/ ¥6.6k(总金额)/ 12(导出记录),18 号 Bold 数值 + 11 号淡灰标签。 - 92% 宽度:左右留 4% 呼吸边距。
- 数据自洽:48 张 ↔ 副标题"48 张" ↔ 分类页 6 类张数之和(12+8+3+15+6+4=48);¥6.6k ↔ 分类页金额之和 6644 元 ≈ 6.6k。
五、MenuList:5 行菜单 + Divider 条件分隔
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: 16 }).backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke })
}
逐点拆解:
- 三栏行:18 号 emoji + 14 号标题(
layoutWeight(1)撑开)+ 14 号 ">" 箭头——系列标准菜单卡。 - Divider 条件分隔:
if (idx < this.menus.length - 1)——最后一行不加 Divider,0.5 细线比 1px 更精致。 - 整行点击:
onClick弹 Toast——5 菜单覆盖搜索/统计/导出/备份/设置。 - "⬆️ 导出报销单":财务场景独有功能——首页"可报销 ¥856"的执行入口,报销是票据管理的闭环终点。


六、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% 透明版本号——margin({ top: 24 }) 与菜单卡拉开距离,系列统一收尾。
七、跨页数据自洽:个人中心的全局闭环
{ value: '48', label: '票据总数' },
Text('管理 48 张票据 · 6600元').fontSize(12).fontColor('#FFFFFF').opacity(0.85)
数据自洽链:
- "48 票据总数" ↔ 副标题"48 张" ↔ 分类页 6 类张数之和(12+8+3+15+6+4=48)。
- "¥6.6k 总金额" ↔ 分类页金额之和 6644 元 ≈ 6.6k。
- 首页"28 张" ↔ 我的页"48 张"——首页是本月口径(28),我的页是累计口径(48),28 + 历史 20 = 48。
- "导出报销单"菜单 ↔ 首页"可报销 ¥856"——856 元是待报销金额,导出报销单是处理这笔钱的动作。

八、系列横向对比:个人中心五种风格
| App | 主题色 | 统计特色 | 独有菜单 |
|---|---|---|---|
| App 52 票据 | #0066CC 科技蓝 | 票据数/总金额/导出 | 导出报销单 |
| App 51 证件照 | #2D3436 深灰 | 历史/导出/规格 | 会员中心 |
| App 45 签到墙 | #FDCB6E 暖黄 | 签到天数/积分 | 活动中心 |
| App 50 室友评价 | #5555AA 靛蓝 | 评分/记录/和谐度 | 匿名评价 |
| App 44 纪念册 | #A29BFE 淡紫 | 留言/相册 | 底部留言栏 |
差异点:App 52 的"导出报销单"是财务场景独有功能——蓝色渐变 + 负边距统计是系列标准范式,"导出报销单"是票据管理的业务特色。
九、开发者视角:调试与验证技巧
- 负边距层级:
.margin({ top: -24 })让统计行叠在渐变卡上——负边距元素必须位于渐变卡之后的兄弟节点(UserCard → StatRow 顺序),且用户卡bottom: 44的留白要与-24匹配(44 > 24,悬浮卡不盖住身份文字)。 - 渐变卡白字透明度:副文案
opacity(0.85)、版本号opacity(0.7)——透明度递减层级(主 1.0 / 副 0.85 / 版本 0.7)。 - Divider 条件渲染:
if (idx < this.menus.length - 1)——最后一项不画分割线,是列表分隔的标准写法。 - 数值展示单位:
¥6.6k缩写 vs 用户卡"6600元"全写——同一数据两种表达,产品化建议统一格式化函数。 - 菜单 key:
m.title5 项内唯一——新增菜单项建议改用m.id作 key。
十、演进方向
| 方向 | 当前状态 | 产品化演进 |
|---|---|---|
| 用户身份 | 写死"票据管家" | 接入账号体系,展示真实用户信息 |
| 统计动态化 | 硬编码 48/¥6.6k/12 | 从数据源实时聚合 |
| 导出报销单 | Toast"导出报销单" | 生成报销单据(PDF/Excel)+ 对接企业报销系统 |
| 云端备份 | Toast"云端备份" | 票据数据云端同步 + 多设备同步 |
| 消费统计 | Toast"消费统计" | 跳分类页分析版(趋势对比 + 占比图表 + 异常提醒) |
十一、一句话总结
我的页以 99 行代码完成了票据管家的个人中心——蓝色渐变 UserCard 配 🧾 票据头像、"票据管家"身份 + "48 张 · 6600 元"数据背书、负边距 margin({ top: -24 }) 悬浮三列统计卡(48/¥6.6k/12)、5 菜单覆盖"搜索/统计/导出/备份/设置"。**"导出报销单"**是财务场景独有功能——首页"可报销 ¥856"的执行入口,让票据管理从"记录"到"报销"形成闭环。

更多推荐





所有评论(0)