news 2026/9/4 4:34:58

ArkTS 严格模式实战:ACG 社区我的页 —— 身份、影响力、成就三层结构组合技

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ArkTS 严格模式实战:ACG 社区我的页 —— 身份、影响力、成就三层结构组合技

ArkTS 严格模式实战:ACG 社区我的页 —— 身份、影响力、成就三层结构组合技

应用背景:12 ACG 社区(acg-community)第四个 Tab 是"我的",对应源码ProfileTab.ets(共 289 行)。它是社区用户的个人中心,玫红主题#DB2777。本文逐行拆解UserInfo 社区身份卡StatGrid 负边距上浮统计AchievementWall 成就墙WeekChart 周活跃度MenuList 功能菜单五大模块,重点讲解"内容社区的个人中心如何用'身份 + 影响力 + 成就'三层结构留住用户",以及它与"工具型应用个人中心"的本质差异。

"我的"页是社区用户"自我身份"的落脚点。相比 11 号校园快递的"我的"页(记录取件数、优惠券等工具性数据),社区的个人中心讲的是另一个故事:我是谁(次元旅人)、我多强(帖子/点赞/粉丝)、我混了多久(加入 365 天)、我拿了什么成就(追番达人/人气作者)。它用"身份 → 影响力 → 成就"三层结构,把一个匿名用户可以变成有归属感的社区成员。读懂这一页,你就掌握了"社交型个人中心"这一高频页面的标准拼装法。

一、数据模型:四类结构

"我的"页用四个接口建模,与 11 号快递同名接口一致,但字段语义随社区业务调整:

interface StatItem { value: string; label: string; } interface BadgeItem { emoji: string; name: string; locked: boolean; } interface WeekBar { day: string; value: number; } interface MenuItem { icon: string; label: string; badge: string; action: string; }

StatItem是统计格;BadgeItem是成就徽章,locked表示是否解锁;WeekBar是周活跃数据;MenuItem是菜单项,badge是角标、action是点击动作。四类接口对应个人中心的四个信息维度:量化(统计)、激励(成就)、趋势(活跃)、导航(菜单)——这个结构在工具型与社交型个人中心里通用,变的只是各维度的"数据内容"。

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

二、页面骨架:单层 Scroll

build() { Column() { Scroll() { Column({ space: 0 }) { this.UserInfo() this.StatGrid() this.AchievementWall() this.WeekChart() this.MenuList() this.AboutInfo() } .width('100%') .padding({ bottom: this.safeBottom + 20 }) } .layoutWeight(1).scrollBar(BarState.Off).align(Alignment.Top) } .width('100%').height('100%').backgroundColor(C.bg) }

Scroll单层包裹、无独立 Header(头像卡即伪 Header),与 11 号一致。注意Column({ space: 0 })——区块间的间距不是靠space,而是各区块自己的margin({ top: 14 })控制(后面会看到 AchievementWall、WeekChart、MenuList 都带margin({ top: 14 }))。这种"space 归零 + 区块各自 margin"的写法,好处是每个区块能独立控制自己的上边距(比如 StatGrid 要负 margin 上浮、其他要正 14 下移),比统一space更灵活。

三、UserInfo 社区身份卡

这是全页的"身份"层。渐变卡里放头像、昵称、等级、加入时长与签到进度:

// UserInfo — 身份卡 @Builder UserInfo() { Column({ space: 14 }) { Row({ space: 14 }) { Column() { Text('🌸').fontSize(34) } .width(64).height(64) .backgroundColor('#33FFFFFF').borderRadius(32) .justifyContent(FlexAlign.Center) Column({ space: 4 }) { Row({ space: 8 }) { Text('次元旅人').fontSize(18).fontWeight(FontWeight.Bold).fontColor('#FFFFFF') Text('Lv.' + this.level).fontSize(11).fontColor('#FFFFFF') .padding({ left: 8, right: 8, top: 2, bottom: 2 }) .backgroundColor('#33FFFFFF').borderRadius(10) } Text('ACG爱好者 · 加入 365 天').fontSize(12).fontColor('#FFFFFF').opacity(0.85) } .alignItems(HorizontalAlign.Start).layoutWeight(1) Column({ space: 4 }) { Text(this.checked ? '✓ 已签到' : '签到').fontSize(12).fontColor('#FFFFFF') .padding({ left: 12, right: 12, top: 6, bottom: 6 }) .backgroundColor(this.checked ? '#33FFFFFF' : '#FFFFFF') .fontColor(this.checked ? '#FFFFFF' : C.primary) .borderRadius(16) .onClick(() => { this.checked = !this.checked; if (this.checked) { this.exp = Math.min(this.exp + 10, 100); } promptAction.showToast({ message: this.checked ? '签到成功 +10 经验' : '已取消' }); }) } .alignItems(HorizontalAlign.End) } .width('100%') Column({ space: 6 }) { Row() { Text('经验值').fontSize(11).fontColor('#FFFFFF').opacity(0.8) Blank() Text(this.exp + ' / 100').fontSize(11).fontColor('#FFFFFF').opacity(0.8) } .width('100%') Progress({ value: this.exp, total: 100 }).color('#FFFFFF').backgroundColor('#33FFFFFF').width('100%') } .width('100%') } .width('100%') .padding({ left: D.pad, right: D.pad, top: this.safeTop + 30, bottom: 24 }) .linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] }) }

结构上与 11 号几乎一致,但处处是"社区"的语义:头像 emoji 是 🌸(樱花,二次元符号)、昵称是「次元旅人」(而非"李同学")、等级是Lv.4、副标题是「ACG爱好者 · 加入 365 天」。

「加入 365 天」这个字段尤其值得一说——它是社区特有的"成员时长"概念,承载"归属感":加入越久、越有"老用户"的身份认同。对比工具型应用(快递)的副标题「梅园 6 栋 302 室」(地理坐标),社区的副标题讲的是"身份认同"而非"物理位置"。个人中心的副标题,本质是"用户最在意的自我标签"——工具用户在意位置、社区用户在意时长,选什么标签,取决于产品想让用户"认同什么"。

签到按钮的exp联动与 11 号一致(Math.min(this.exp + 10, 100)封顶),ProgressbackgroundColor('#33FFFFFF')让经验条在玫红底上有半透明白的轨道。this.exp初始值 55、签到后 65,驱动进度条与百分比文字同步刷新——"一处状态、多处联动"的迷你示范再次上演。

四、StatGrid 负边距上浮统计

统计网格用margin({ top: -28 })上浮,压在身份卡底边,形成层叠:

// StatGrid — 统计网格 @Builder StatGrid() { 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).alignItems(HorizontalAlign.Center) }, (s: StatItem) => s.label) } .width('90%') .padding({ top: 16, bottom: 16 }) .backgroundColor(C.card) .borderRadius(D.rLg) .border({ width: 1, color: C.stroke }) .margin({ top: -28, left: D.pad, right: D.pad }) .shadow({ radius: 12, color: '#10000000', offsetX: 0, offsetY: 4 }) }

"负 margin 上浮 + 阴影"的层叠技巧与 11 号一致(margin({ top: -28 })+.shadow(...)),但数据是社区影响力指标:「我的帖子 15 / 获赞总数 1.2k / 粉丝 286 / 关注 128」。这四栏是社交平台衡量用户价值的核心四元组——发帖数(产出)、获赞数(质量)、粉丝数(影响力)、关注数(关系网),与工具型的"取件数/代取次数/优惠券/收件地址"形成鲜明对比。

width('90%')让统计卡比身份卡略窄,左右各留出D.pad,浮起时两侧露出身份卡边角,层叠感更强。四个数字里1.2k用缩写、286/128用全数字,混排是社区数据的常态——大数用k缩写、小数保留全量,平衡可读性与精度。

五、AchievementWall 成就墙

成就墙是"激励"层,六枚勋章用opacity区分已解锁/未解锁:

// AchievementWall — 成就墙 @Builder AchievementWall() { Column({ space: 12 }) { Text('成就墙').fontSize(16).fontWeight(FontWeight.Bold).fontColor(C.text).width('100%') Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.SpaceBetween }) { ForEach(this.badges, (b: BadgeItem) => { Column({ space: 6 }) { Row() { Text(b.emoji).fontSize(28).opacity(b.locked ? 0.4 : 1) } .width(52).height(52) .backgroundColor(b.locked ? C.cardSoft : C.primarySoft) .borderRadius(26) .justifyContent(FlexAlign.Center) Text(b.name).fontSize(10).fontColor(b.locked ? C.textDim : C.textSub) Text(b.locked ? '未解锁' : '已获得').fontSize(9).fontColor(b.locked ? C.textDim : C.primary) } .width('30%') .padding({ top: 10, bottom: 10 }) .alignItems(HorizontalAlign.Center) .onClick(() => { promptAction.showToast({ message: b.locked ? b.name + '(未解锁)' : b.name + '(已获得)' }); }) }, (b: BadgeItem) => b.name) } .width('100%') } .width('100%').padding(14) .backgroundColor(C.card).borderRadius(D.rLg) .border({ width: 1, color: C.stroke }) .margin({ top: 14, left: D.pad, right: D.pad }) }

六枚成就「人气作者 🏆 / 追番达人 🌸 / 创作之星 🎨 / 热议先锋 🔥 / 精华作者 ⭐ / 年度元老 👑」,前四枚解锁、后两枚锁定。锁定态用.opacity(0.4)淡化 emoji +C.cardSoft灰底 + 灰字「未解锁」,已获得用C.primarySoft玫红浅底 + 玫红字「已获得」。这个"灰掉未解锁项"的手法与 11 号一致,但成就名称从"取件达人/代取先锋"变成了"人气作者/追番达人/创作之星"——工具型的成就是"任务达成",社区型的成就是"身份勋章"

社区成就墙的产品价值是"身份认同 + 游戏化留存":用户看到「追番达人」「创作之星」这些勋章,会产生"我是这个圈子的一员、我擅长 XX"的归属感,进而更愿意持续发帖、追番、创作来解锁更多勋章。成就名称越贴近社区文化(追番、创作、热议),认同感越强。这是内容社区留存的核心手段之一,比单纯签到更有效。

六、WeekChart 周活跃度

周活跃条形图与前作共享同一套公式,但数据是"社区活跃度":

// WeekChart — 周活跃 @Builder WeekChart() { Column({ space: 12 }) { Row() { Text('本周社区活跃度').fontSize(15).fontWeight(FontWeight.Bold).fontColor(C.text) Blank() Text('连续 7 天').fontSize(12).fontColor(C.primary) }.width('100%') Row({ space: 6 }) { ForEach(this.weekBars, (w: WeekBar) => { Column({ space: 6 }) { Column() { Column() .width('100%') .height(Math.floor(w.value / this.maxBar * 70)) .backgroundColor(C.primary).borderRadius(4) }.width('100%').height(70) Text(w.day).fontSize(11).fontColor(C.textDim) } .layoutWeight(1).alignItems(HorizontalAlign.Center) }, (w: WeekBar) => w.day) }.width('100%') } .width('100%').padding(14) .backgroundColor(C.card).borderRadius(D.rLg) .border({ width: 1, color: C.stroke }) .margin({ top: 14, left: D.pad, right: D.pad }) }

公式Math.floor(w.value / this.maxBar * 70)与首页一致(高度 70 而非首页的 80,因为"我的"页的图表要更紧凑)。右侧标签「连续 7 天」用C.primary玫红高亮——"连续天数"是社区活跃度的关键指标,用户看到"连续 7 天"会产生"不能断签/断更"的心理压力,驱动每日回访。

数据[65, 88, 52, 95, 78, 90, 72]与首页 WeekChart 完全相同——这暴露了一个值得注意的点:首页的"发帖趋势"和"我的"页的"活跃度"用了同一组数据。在 demo 里这是合理的简化,但真实项目中两者应来自不同数据源(首页是"全社区发帖量",我的页是"我个人活跃度")。这个细节提醒我们:系列化 demo 为了省事常复用 mock 数据,读者接真实数据时要逐一核对语义,别把"全站数据"错当成"个人数据"。

七、MenuList 功能菜单

菜单区是"导航"层,六项功能收拢,带角标:

// MenuList — 功能菜单 @Builder MenuList() { Column({ space: 0 }) { ForEach(this.menus, (m: MenuItem) => { Row({ space: 12 }) { Row() { Text(m.icon).fontSize(20) } .width(36).height(36) .backgroundColor(C.cardSoft).borderRadius(D.rSm) .justifyContent(FlexAlign.Center) Text(m.label).fontSize(14).fontColor(C.text).layoutWeight(1) if (m.badge.length > 0) { Text(m.badge).fontSize(11).fontColor(C.danger) .padding({ left: 8, right: 8, top: 2, bottom: 2 }) .backgroundColor(C.primarySoft).borderRadius(8) } Text('>').fontSize(14).fontColor(C.textDim) } .width('100%') .padding({ left: 14, right: 14, top: 12, bottom: 12 }) .onClick(() => { promptAction.showToast({ message: m.action }); }) if (m.label !== '帮助反馈') { Divider().color(C.stroke).strokeWidth(0.5).margin({ left: 62 }) } }, (m: MenuItem) => m.label) } .width('100%') .backgroundColor(C.card) .borderRadius(D.rLg) .border({ width: 1, color: C.stroke }) .margin({ top: 14, left: D.pad, right: D.pad }) }

六项「我的帖子 15 / 我的收藏 8 / 关注/粉丝 / 消息通知 12 / 隐私设置 / 帮助反馈」,是社区功能的完整导航。if (m.badge.length > 0)条件渲染角标(我的帖子 15、我的收藏 8、消息通知 12 带角标),角标用C.danger(红)字 +C.primarySoft(玫红浅底)。if (m.label !== '帮助反馈')控制 Divider 的显隐——最后一项不画分隔线,与 11 号的"分组圆角"写法不同,这里是"靠 Divider 分隔"的实现,更直接。

菜单项里的「关注/粉丝」「隐私设置」是社交型个人中心的特有入口——工具型(快递)只有"优惠券/地址/代取"等功能项,而社区多了"社交关系(关注/粉丝)"和"隐私(匿名发布相关)"。个人中心菜单的差异,直接反映产品的核心能力:社区关心关系与隐私,工具关心功能与效率。

八、AboutInfo 关于信息

// AboutInfo — 关于 @Builder AboutInfo() { Column({ space: 6 }) { Text('ACG社区 v1.0.0').fontSize(12).fontColor(C.textDim) Text('Powered by HarmonyOS 6.0+ · ArkTS').fontSize(11).fontColor(C.textDim) Text('© 2025 次元壁').fontSize(10).fontColor(C.textDim) } .width('100%').padding({ top: 20, bottom: 10 }).alignItems(HorizontalAlign.Center) }

页脚三行:版本号 + 技术栈 + 版权「© 2025 次元壁」。版权归属「次元壁」是社区品牌名,与首页头图的 Slogan「次元壁 · ACG爱好者的家」呼应——品牌名贯穿头图与页脚,形成闭环。这个细节很小,但体现了品牌一致性:一个应用的所有文案(头图 Slogan、页脚版权、关于信息)应指向同一个品牌,而非散乱的名字。

九、社交型 vs 工具型个人中心的本质差异

把 12 号(社区)与 11 号(快递)的"我的"页并排看,结构几乎一致(UserInfo / StatGrid / AchievementWall / WeekChart / MenuList / AboutInfo 六件套),但每个模块的"数据语义"完全不同:

模块工具型(快递)社交型(社区)
身份卡副标题梅园 6 栋 302 室(位置)ACG爱好者 · 加入 365 天(身份+时长)
统计四栏取件数/代取/优惠券/地址(功能)帖子/获赞/粉丝/关注(影响力)
成就墙取件达人/代取先锋(任务)人气作者/追番达人(身份勋章)
菜单优惠券/地址/代取/安全中心(功能)帖子/收藏/关注/粉丝/隐私(关系+隐私)

结论清晰:工具型个人中心是"功能面板",社交型个人中心是"身份档案"。前者回答"我能用哪些功能",后者回答"我是谁、我多强、我混了多久"。这个区分决定了个人中心的整体气质——工具型偏"冷静、高效",社交型偏"情感、认同"。同一套六件套骨架,因数据语义不同而呈现出完全不同的性格,这正是"骨架复用、语义重写"的又一次印证。

十、本章小结与工程经验

模块核心技术学习价值
UserInfo渐变身份卡 + exp 进度联动社区身份卡
StatGridmargin({ top: -28 })负边距浮起影响力四栏
AchievementWallopacity(locked?0.4:1)锁定淡化身份勋章体系
WeekChart复用条形图公式社区活跃度
MenuListif(badge)角标 + Divider功能导航
AboutInfo品牌闭环页脚品牌一致性

"我的"页最大的收获是"社交型个人中心"范式:身份卡(昵称 + 等级 + 加入时长)→ 影响力四栏(帖子/获赞/粉丝/关注)→ 成就墙(身份勋章)→ 活跃度图 → 功能菜单。这套"身份 → 影响力 → 成就 → 导航"的四层结构,几乎能覆盖一切社交/内容/社区类应用的个人中心。

其次要记住两个技术点(与 11 号呼应但值得重复):负 margin 制造层叠margin({ top: -28 })+ 阴影让统计卡浮起)、状态透明化渲染(未解锁成就用opacity淡化而非隐藏)。最后,品牌文案要贯穿全应用——头图 Slogan「次元壁 · ACG爱好者的家」与页脚「© 2025 次元壁」前后呼应,是品牌一致性的最小成本体现。

十一、签到与经验:社区留存的游戏化引擎

签到按钮是全页唯一真正改变状态的点——点击后this.checked翻转、this.exp = Math.min(this.exp + 10, 100)经验 +10、Toast 提示"+10 经验"。这背后是社区应用的"游戏化留存"机制:签到 → 经验 → 等级 → 成就 → 身份,一条完整的激励链路。

this.exp同时驱动进度条Progressvalue和文字this.exp + ' / 100',一处状态、两处联动。Math.min把经验封顶 100%,避免连点签到撑爆进度条。等级Lv.4目前是写死的@State level,真实项目应由经验值换算而来(如level = Math.floor(exp / 25) + 1),经验满 100 升级、等级提升又解锁更多成就徽章。

这套"签到 → 经验 → 等级 → 成就"的闭环,是社区留存最经典的手段:签到制造"每日回访"习惯,经验/等级提供"成长感",成就墙提供"身份认同"。三者叠加,让用户从"偶尔看看"变成"每天回来"。11 号快递也有签到(exp初始 72),但社区的签到与成就墙、等级、加入天数形成了更强的联动叙事——工具型签到是"薅羊毛",社区型签到是"养成"。

十二、社交数据的一致性与来源

"我的"页的统计数据(我的帖子 15、获赞 1.2k、粉丝 286、关注 128)与首页 HeroCard(今日新帖 128)、我的动态页 OverviewCard(我的帖子 15、获赞 1.2k、粉丝 286)相互呼应——"我的帖子 15"在"我的"页和"我的动态"页同时出现,数据一致。这种"跨页数据一致"在 demo 里是刻意编排的,真实项目里则应来自同一个用户画像接口,避免各页各存一份导致数据打架。

这提醒我们:个人中心、动态页、首页的用户数据,都应指向同一个"用户画像"数据源(userProfile),各页只是这个画像的不同视图。数据源唯一,UI 怎么裁剪都不会自相矛盾——这是本系列反复强调的"单一数据源"原则在个人中心的又一次印证。

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

物联网系统设计实战:从传感器到云端的智能蜂箱解决方案

简介:这是一套面向嵌入式初学者与毕设/课设学生的物联网智能蜂箱完整软硬件解决方案,聚焦STM32平台开发,解决农业物联网场景中环境监测、数据上传与远程管理等核心问题,适用于毕业设计、课程设计、工程实训及大创项目等实践环节。…

作者头像 李华
网站建设 2026/9/4 4:30:11

AD8232与STM32心电采集系统:硬件设计、ADC配置与实时滤波实战

简介:本资源是一套面向嵌入式初学者与健康电子项目开发者的AD8232心电采集系统完整实现方案,聚焦STM32F10x系列微控制器与AD8232模拟前端芯片的硬件接口与软件驱动开发。资源解决了ECG信号采集、ADC采样配置、数字滤波处理及R-R间隔检测等核心问题&#…

作者头像 李华
网站建设 2026/9/4 4:28:52

FM17550 LPCD低功耗卡片检测实战:从原理到调优全解析

简介:本资源是面向嵌入式开发工程师与低功耗物联网系统设计者的FM17550LPDC芯片LPCD(数据通信期间低功耗)模式实战例程,聚焦解决电池供电设备中通信与功耗难以兼顾的核心痛点。资源包共126个文件,含39个头文件&#xf…

作者头像 李华
网站建设 2026/9/4 4:28:21

开源本地优先AI工作站:从架构选型到许可证合规的完整实践

把“本地优先”写进项目定位后,好几个同行跑来问我:你这是不是在和主流趋势对着干?现在各家都拼命把能力往云端塞,你却坚持把数据和推理都留在自己机器里,还要把代码整个开源、允许自由商用、接受所有人审计。我说这不…

作者头像 李华
网站建设 2026/9/4 4:27:19

2026 模型路由实战:把分流契约写进SPEC,MonkeyCode 云端跑通

老陈带 6 人小队给省级人社厅做就业补贴资格预审助手。客户口头说得很清楚:简单政策问答走便宜快模型,材料完整性核验走中等模型,涉及补贴金额和资格结论必须走强模型再人工复核。结果上线第一周就炸了——Qwen 把所有工单都丢给最贵模型&…

作者头像 李华