news 2026/9/7 17:25:43

鸿蒙原生应用 HarmonyOS ArkTS 实战:阅读管理我的页等级卡与成就徽章墙组合技

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙原生应用 HarmonyOS ArkTS 实战:阅读管理我的页等级卡与成就徽章墙组合技

鸿蒙原生应用 HarmonyOS ArkTS 实战:阅读管理我的页等级卡与成就徽章墙组合技

App 20「阅读管理」我的 Tab(ProfileTab),是个人中心页。整页用渐变用户卡片(小明同学 + Lv.4 + 距 Lv.5 还需 120 经验 + 74% 经验条)+ 4 栏彩色统计(历史订单 28/进行中 3/满意度 98%/连续天数 15)+ 本周使用条形图(20 次/周六高亮)+ 6 徽章成就墙(4 解锁 2 未解锁)+ 5 项菜单(我的收藏带 NEW 角标)+ About。与 App 13 我的页几乎完全同源(连"历史订单/省钱能手"都保留)——是模板复刻的最完整示范。本篇基于20-reading-manager/entry/src/main/ets/pages/ProfileTab.ets(约 226 行)逐段拆解,附 4 张实机截图。

一、整体结构:6 个 @Builder 的紫色个人中心

ProfileTab 的结构与 App 13/17 我的页完全同源(0 个 @State):

build() { Column() { Scroll() { Column({ space: 0 }) { this.UserCard() this.StatRow() this.WeekChartCard() this.AchievementWall() 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) }

6 个块顺序:UserCard(身份)→ StatRow(数据)→ WeekChartCard(行为图)→ AchievementWall(成就)→ MenuList(资产)→ About(关于)。

space: 0让 UserCard 和 StatRow 紧贴——StatRowmargin({ top: -28 })上浮形成"卡片叠加"悬浮效果。

与 App 13 完全同源——6 块顺序、布局、负边距悬浮完全一致。唯一差异:主题色(紫 #8B5CF6 → 紫 #A855F7)。

项目源码开源:https://gitee.com/codenestFlow/HarmonyOSHub

二、UserCard:渐变 + Lv.4 + 经验条 + 签到

UserCard 与 App 13 我的页同构(Stack 头像/Lv.4 徽章 + 姓名/认证/Slogan + 经验条 + 签到/数据报告双按钮):

@Builder UserCard() { Column({ space: 12 }) { Row({ space: 14 }) { Stack({ alignContent: Alignment.BottomEnd }) { Row() { Text('👤').fontSize(34) } .width(60).height(60).backgroundColor('rgba(255,255,255,0.35)').borderRadius(D.rLg).justifyContent(FlexAlign.Center) .border({ width: 2, color: 'rgba(255,255,255,0.7)' }) Row() { Text('Lv.4').fontSize(9).fontColor('#FFFFFF').fontWeight(FontWeight.Bold) } .padding({ left: 5, right: 5, top: 1, bottom: 1 }) .backgroundColor(C.warn).borderRadius(4).border({ width: 1.5, color: '#FFFFFF' }) } Column({ space: 5 }) { Row({ space: 8 }) { Text('小明同学').fontSize(18).fontWeight(FontWeight.Bold).fontColor('#FFFFFF') Text('认证').fontSize(9).fontColor('#FFFFFF') .backgroundColor('rgba(255,255,255,0.3)').padding({ left: 5, right: 5, top: 1, bottom: 1 }).borderRadius(3) } Text('活跃用户 · 已使用 28 天').fontSize(11).fontColor('rgba(255,255,255,0.85)') Row({ space: 4 }) { Text('距 Lv.5 还需').fontSize(9).fontColor('rgba(255,255,255,0.7)') Text('120').fontSize(11).fontColor('#FFFFFF').fontWeight(FontWeight.Bold) Text('经验').fontSize(9).fontColor('rgba(255,255,255,0.7)') } Stack({ alignContent: Alignment.Start }) { Column().width('100%').height(4).backgroundColor('rgba(255,255,255,0.25)').borderRadius(2) Column().width('74%').height(4).backgroundColor('#FFFFFF').borderRadius(2) }.width(140) }.alignItems(HorizontalAlign.Start).layoutWeight(1) }.width('100%').padding({ left: D.pad, right: D.pad, top: this.safeTop + 30, bottom: 16 }) Row() { Row({ space: 5 }) { Text('🎁').fontSize(11) Text('每日签到').fontSize(11).fontColor('#FFFFFF') } .padding({ left: 12, right: 12, top: 6, bottom: 6 }) .backgroundColor('rgba(255,255,255,0.2)').borderRadius(D.rSm) .onClick(() => { promptAction.showToast({ message: '签到成功 +5 经验' }); }) Blank() Row({ space: 5 }) { Text('📊').fontSize(11) Text('数据报告').fontSize(11).fontColor('#FFFFFF') } .padding({ left: 12, right: 12, top: 6, bottom: 6 }) .backgroundColor('rgba(255,255,255,0.2)').borderRadius(D.rSm) .onClick(() => { promptAction.showToast({ message: '数据报告' }); }) }.width('100%').padding({ left: D.pad, right: D.pad, bottom: 14 }) } .width('100%').linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] }) }

2.1 身份设定

  • 头像 + Lv.4 徽章(Stack BottomEnd):60×60 半透明白头像 + 橙底白边 Lv.4 徽章(C.warn
  • 姓名:"小明同学" + "认证"标签
  • Slogan:"活跃用户 · 已使用 28 天"——时长叙事(对比 App 18 的"匹配率"、App 19 的"社团地位",App 20 是"使用时长")
  • 经验:"距 Lv.5 还需 120 经验" + 74% 白色进度条

Lv.4 徽章用橙色(C.warn——等级徽章用警示色形成"显著标记"(App 13/17/20 同款)。

2.2 伪签到(不改变状态)

Row() { Row({ space: 5 }) { Text('🎁').fontSize(11) Text('每日签到').fontSize(11).fontColor('#FFFFFF') } .padding({ left: 12, right: 12, top: 6, bottom: 6 }) .backgroundColor('rgba(255,255,255,0.2)').borderRadius(D.rSm) .onClick(() => { promptAction.showToast({ message: '签到成功 +5 经验' }); }) ...

签到只弹 Toast("签到成功 +5 经验")不改变状态——"伪签到"(App 13/17 同款,App 18/19 是"真签到 exp+=10")——**"0 @State 个人中心的签到是伪交互"**是模板复刻的简化(读者想看真签到参考 App 18/19)。

"+5 经验"的数值(App 13/17/20 都是 +5)——"经验值参数"跟随模板(App 18/19 是 +10)。

2.3 紫色 135° 渐变

.width('100%').linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] })

#A855F7 → #C084FC135° 渐变——左上浓紫、右下浅紫——"紫色个人中心"(阅读 App 的"知识深度"调性)。

三、StatRow:4 栏统计(模板遗留)

StatRow 是 4 栏统计(历史订单 28/进行中 3/满意度 98%/连续天数 15),与 App 13 完全同源

private stats: StatItem[] = [ { value: '28', label: '历史订单', color: C.primary }, { value: '3', label: '进行中', color: C.accent }, { value: '98%', label: '满意度', color: C.ok }, { value: '15', label: '连续天数', color: C.warn } ];

关键问题:"历史订单/满意度"是电商统计,不是阅读统计——"个人中心统计没换业务"(App 13 音乐订单模板原样保留)——这是 App 20 模板复刻最明显的遗留

App 13(音乐)App 20(阅读)应改为
历史订单 28已读书籍 36
进行中 3在读 3
满意度 98%阅读时长 128h
连续天数 15读书笔记 246

"统计项没换"让 App 20 的我的页与首页(已读书籍 36)数据矛盾(首页 36、我的页 28)——**"跨页数据不一致"**是本页最大的瑕疵(首页已读书籍 36 vs 我的页历史订单 28)——读者必须引以为戒:换业务必换所有数据

4 栏彩色(紫/浅紫/绿/橙)——"颜色留给状态"。

四、WeekChartCard:本周使用条形图

WeekChartCard 与 App 13 同构(7 天条形图 + 20 次/周六高亮):

@Builder WeekChartCard() { Column({ space: 12 }) { Row() { Text('📈 本周使用').fontSize(15).fontWeight(FontWeight.Bold).fontColor(C.text) Blank() Text('20 次').fontSize(13).fontWeight(FontWeight.Bold).fontColor(C.primary) }.width('100%') Row({ space: 4 }) { ForEach(this.weekBars, (b: WeekBar, idx: number) => { Column({ space: 6 }) { Column() .width(18) .height(Math.max(6, b.value / 5 * 80)) .borderRadius(4) .linearGradient({ angle: 180, colors: idx === 5 ? [[C.primary, 0.0], [C.accent, 1.0]] : [[C.primarySoft, 0.0], [C.primary, 1.0]] }) Text(b.day).fontSize(10).fontColor(idx === 5 ? C.primary : C.textDim) .fontWeight(idx === 5 ? FontWeight.Bold : FontWeight.Normal) }.layoutWeight(1).alignItems(HorizontalAlign.Center) }, (b: WeekBar) => b.day) }.width('100%') } .width('100%').padding(14).backgroundColor(C.card).borderRadius(D.rMd) .border({ width: 1, color: C.stroke }) .margin({ top: 14, left: D.pad, right: D.pad }) }

数据:2/3/1/4/3/5/2——周六(idx=5)value=5 最高、周三(idx=1? 不对,idx=2 周三 value=1)最低——周六高亮idx === 5写死)。

b.value / 5 * 80归一化(最大值 5 → 80vp)。汇总"20 次":2+3+1+4+3+5+2 = 20 ✓——严格自洽

"本周使用 20 次"在阅读 App 里是"打开 20 次"(次数 vs 首页的"时长"——"次数"和"时长"两个度量混用又是口径问题,但"20 次 = 各柱之和"至少数学自洽)。

五、AchievementWall:6 徽章成就墙(模板遗留)

AchievementWall 是 6 个徽章(4 解锁 2 未解锁),与 App 13 完全同源

private achievements: Achievement[] = [ { icon: '🎯', title: '初次使用', unlocked: true, desc: '第一次下单' }, { icon: '🔥', title: '活跃用户', unlocked: true, desc: '使用7天' }, { icon: '⭐', title: '好评达人', unlocked: true, desc: '5星好评10次' }, { icon: '💰', title: '省钱能手', unlocked: true, desc: '节省100元' }, { icon: '👑', title: '资深用户', unlocked: false, desc: '使用100天' }, { icon: '💎', title: '完美用户', unlocked: false, desc: '满意度100%' } ];

关键问题(同 StatRow):"第一次下单/好评达人/省钱能手/节省100元"是电商徽章,不是阅读徽章——**"成就徽章没换业务"**是 App 20 模板复刻的最大遗留:

App 13 徽章App 20(阅读)应改为
初次使用(第一次下单)初读体验(读完第一本书)
好评达人(5星好评10次)阅读达人(累计阅读100小时)
省钱能手(节省100元)藏书阁(收藏100本书)
完美用户(满意度100%)大师读者(读完50本书)

"省钱能手"出现在阅读 App 的违和感(和 App 17 志愿版一样的问题)——**"徽章 = 业务成就"**是必须遵守的原则。

解锁/未解锁三件套(背景/透明度/文字)+4/6动态计算.filter(a => a.unlocked).length)——App 13/20 用动态计算(App 14/15/16 硬编码)。

六、MenuList + About

MenuList 是 5 项菜单(历史订单/消费统计/提醒设置/我的收藏/设置),我的收藏带 NEW 角标

private menus: MenuItem[] = [ { id: 1, emoji: '📦', title: '历史订单', desc: '查看所有历史记录', badge: '' }, { id: 2, emoji: '📊', title: '消费统计', desc: '月度数据分析', badge: '' }, { id: 3, emoji: '🔔', title: '提醒设置', desc: '订单状态通知', badge: '' }, { id: 4, emoji: '⭐', title: '我的收藏', desc: '常用列表', badge: 'NEW' }, { id: 5, emoji: '⚙️', title: '设置', desc: '账号与隐私', badge: '' } ];

同 StatRow 的问题:"历史订单/消费统计/订单状态通知"是电商菜单——"菜单没换业务"(阅读 App 应改为"阅读记录/读书笔记/书签管理/阅读偏好"等)。

角标:NEW →C.ok绿(App 13/17/20 同款:NEW 用绿、数字用红)——m.badge.length > 0条件渲染 +Divider().margin({ left: 58 })分隔线。

AboutVersion 1.0.0+HarmonyOS 6.0+ · ArkTS · API 23两行(App 13 同款)。

七、@State 数量 = 0(模板遗留)

ProfileTab0 个 @State——所有数据private不可变,签到是"伪签到"。

4 个 Tab 的 @State 分布(App 20):

页面@State 数量类型
首页1(searchText)展示+搜索
书库5(表单)创建表单
记录1(activeTab)筛选
我的0纯展示

**"0 @State 个人中心"是 App 13/17/20 这条"模板复刻线"的标准(App 18/19 是 3 个 @State 的真签到)——"模板复刻 vs 功能进化的两条线"**在系列里并行。

八、"模板复刻"的正反面教材

App 20 我的页是系列"模板复刻"的最完整示范(App 13 紫 #8B5CF6 → App 20 紫 #A855F7),也是最典型的反面教材

复刻对了的

  • 主题色(紫 #A855F7 + 浅紫 + 渐变)
  • 布局(6 块结构 + 负边距悬浮)
  • 组件(Stack 头像/Lv 徽章/进度条/Toggle/角标)
  • 交互(@Builder 拆分 + @State 管理)

没换的(反面教材)

  • 统计(历史订单/满意度 → 应是已读书籍/时长)
  • 徽章(省钱能手 → 应是阅读成就)
  • 菜单(历史订单/消费统计 → 应是阅读记录/书签)
  • 文案("下单""订单" → 应是"阅读""笔记")

"换主题不换业务"是模板复刻的最大陷阱——用户打开"阅读管理"却看到"省钱能手"徽章,违和感极强真实项目套用模板必须"数据 + 文案全换"

正面示范(App 18/19):App 18 社交、App 19 摄影的个人中心完全定制了业务数据(社交徽章/摄影徽章/业务统计)——"换主题 + 换业务 = 成功复刻"

九、阅读 App 个人中心的"业务化改造清单"

对比 App 13(音乐)与 App 20(阅读)的个人中心,整理一份**"业务化改造清单"**——读者套用任何个人中心模板时按此清单逐项替换:

模板项App 13(音乐)App 20(阅读)应改为
用户名小明同学读者小明(或"书友")
Slogan活跃用户·已使用28天阅读达人·累计阅读128小时
统计1历史订单 28已读书籍 36
统计2进行中 3在读 3
统计3满意度 98%阅读时长 128h
统计4连续天数 15读书笔记 246
徽章初次使用/好评达人/省钱能手初读体验/阅读达人/藏书阁
菜单历史订单/消费统计阅读记录/读书笔记
周图本周使用 20 次本周阅读 20 次
签到+5 经验+10 阅读经验

"个人中心业务化"的 5 大块:用户/统计/徽章/菜单/周图——每块都要随业务换

判断标准:把 App 20 的每个字读一遍,"出现'订单/消费/省钱'就是没换干净"——"业务词检测"是最快的复刻验收法(搜索"订单/消费/省钱/下单"关键词,有残留就换)。

十、个人中心模板的"系列演变线"

回顾系列 6 个"个人中心"(App 13/14/15/16/17/18/19/20 中选代表性的),可以看清两条演变线:

线 1:模板复刻线(骨架复用、业务未换)

App用户等级业务数据
13 音乐小明同学Lv.4订单/省钱(音乐场景违和)
17 志愿小明同学Lv.4订单/省钱(志愿场景违和)
20 阅读小明同学Lv.4订单/省钱(阅读场景违和)

线 2:业务定制线(骨架 + 业务全换)

App用户等级业务数据
14 运动张运动Lv.5预约/时长/卡路里
15 环保李环保Lv.6分类/准确率/减碳
16 商城王积分Lv.7积分/兑换/收藏
18 社交张同学Lv.8好友/互动/匹配率
19 摄影摄影爱好者Lv.6作品/点赞/获奖

对比结论"业务定制线"的 5 个 App 是成功的模板复用(数据/徽章/菜单全换);"模板复刻线"的 3 个 App 是偷懒的模板复用(只换主题色)。读者应学习线 2、警惕线 1——"复用模板"和"复制模板"只有一字之差,质量天壤之别。

"等级递进"的彩蛋:业务定制线等级 5→6→7→8→6 递增(反映"每个 App 用户更资深"的叙事),模板复刻线固定 Lv.4——"等级 = 业务定制的深度信号"

十一、总结

App 20「阅读管理」我的页解析完毕。Lv.4 紫色个人中心是 App 13 模板的最完整复刻,同时也是"换主题不换业务"的反面教材——读者应对比 App 18/19 的"业务定制版"学习正确的模板复用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 17:25:37

【单片机课程设计/毕业设计】基于 STM32 单片机的室内种植环境监测控制系统设计与实现 基于 STM32 单片机的多模式农业环境智能调控系统设计(010507)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华
网站建设 2026/9/7 17:23:40

DMA工作原理与实战:从数据搬运到串口接收、ADC采样

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 17:22:54

OSS PDF下载到指定文件夹:从原理到批量落地的完整方案

平时处理OSS里的PDF文件,最头疼的往往不是上传,反而是下载。尤其当你想把某个PDF直接落到本地指定文件夹,而不是让浏览器随手丢进“下载”目录时,各种小问题就冒出来了:文件名乱码、下载一半失败、明明有权限却报403、…

作者头像 李华
网站建设 2026/9/7 17:21:00

Java工程师必备:9个提升开发效率的工具库

做了这么多年Java开发,我一直有个观点:真正拉开开发效率差距的,往往不是语言本身,而是你手里工具库的熟练度。同一个CRUD接口,有人能在一个小时内搞定,有人要磨蹭一整天,区别就在这。今天把我一…

作者头像 李华
网站建设 2026/9/7 17:20:40

Git命令找不到?三平台PATH环境变量配置与排查完整指南

你是不是也遇到过这种情况:明明刚装完Git,打开终端敲 git --version ,结果屏幕冷冷地回一句 git: command not found ,Windows 上是 git 不是内部或外部命令 。这不是Git没装上,多数时候是PATH环境变量没配好。今…

作者头像 李华