鸿蒙原生应用实战:HarmonyOS 6.0 条件渲染驱动社区互动页四分类切换与通知进度条
鸿蒙原生应用实战HarmonyOS 6.0 条件渲染驱动社区互动页四分类切换与通知进度条App 19「校园影像」社区 TabFunc2Tab是互动通知中心——4 栏彩色统计新点赞/新评论/新粉丝/系统 4 分类下划线 Tab全部/点赞/评论/系统真实切换不同列表if/else条件渲染 通知卡片带进度条 动态卡片小明 点赞了你的 「校园日出」式互动叙事。本篇基于19-campus-photo/entry/src/main/ets/pages/Func2Tab.ets约 235 行逐段拆解附 4 张实机截图。一、整体结构4 分类真切换与 App 18 消息页同源Func2Tab 的骨架与 App 18 消息页几乎完全同构——Header 4 栏统计 4 分类 Tab if/else 切换列表build() { Column() { this.Header() this.StatOverview() this.TabBar() if (this.currentTab 0) { this.AllList() } else if (this.currentTab 1) { this.LikeList() } else if (this.currentTab 2) { this.CommentList() } else { this.SystemList() } } .width(100%).height(100%).backgroundColor(C.bg) }4 分类currentTab 0→ AllList通知区 动态区currentTab 1→ LikeList点赞动态筛选currentTab 2→ CommentList评论动态筛选else3→ SystemList系统通知与 App 18 的差异App 18 是全部/未读/好友申请/系统通知App 19 是全部/点赞/评论/系统——未读/好友申请换成点赞/评论——通知分类跟随业务摄影社区的通知是点赞/评论/粉丝而非好友申请。项目源码开源https://gitee.com/codenestFlow/HarmonyOSHub二、Header StatOverview4 栏彩色统计Header 单行标题消息通知。StatOverview 是 4 栏统计新点赞 28/新评论 12/新粉丝 5/系统 3每栏带颜色private stats: StatItem[] [ { value: 28, label: 新点赞, color: C.danger }, { value: 12, label: 新评论, color: C.primary }, { value: 5, label: 新粉丝, color: C.ok }, { value: 3, label: 系统, color: C.accent } ];4 色映射新点赞 28 →C.danger红点赞热度信号新评论 12 →C.primary青绿评论互动主色新粉丝 5 →C.ok绿粉丝成长系统 3 →C.accent浅青绿系统中性点赞用红色——点赞数在摄影 App 里是最显眼的互动信号首页作品卡 ❤ 也是红色。三、TabBar4 段下划线TabBar 与 App 18 同构4 段 24×3 下划线 底部横线Builder TabBar() { Row() { ForEach(this.tabs, (t: string, idx: number) { Column({ space: 4 }) { Text(t).fontSize(13) .fontColor(this.currentTab idx ? C.primary : C.textDim) .fontWeight(this.currentTab idx ? FontWeight.Bold : FontWeight.Normal) Row().width(24).height(3).borderRadius(2) .backgroundColor(this.currentTab idx ? C.primary : transparent) }.layoutWeight(1).padding({ top: 12, bottom: 8 }) .onClick(() { this.currentTab idx; }) }, (t: string, idx: number) t idx) } .width(100%).backgroundColor(C.card).margin({ top: 12 }) .border({ width: { bottom: 1 }, color: C.stroke }) }选中态青绿下划线 青绿加粗文字 vs 灰字。onClick(() { this.currentTab idx; })切换 →if/else重渲染列表——Tab 真切换。四、AllList通知区 动态区AllList全部 Tab是通知区4 条通知 动态区4 条动态双分区Builder AllList() { Scroll() { Column({ space: 12 }) { this.NoticeSection() this.ActivitySection() } .width(100%) .padding({ left: D.pad, right: D.pad, top: 12, bottom: D.pad this.safeBottom 20 }) } .layoutWeight(1).scrollBar(BarState.Off).align(Alignment.Top) }通知在上、动态在下系统消息优先、互动动态次要——与 App 18 同款双分区结构。4.1 NoticeCard带进度条的通知卡本页特色Builder NoticeCard(n: NotifyItem) { Column({ space: 10 }) { Row({ space: 12 }) { Row() { Text(n.icon).fontSize(24) } .width(44).height(44).backgroundColor(C.primarySoft).borderRadius(22).justifyContent(FlexAlign.Center) Column({ space: 4 }) { Row() { Text(n.title).fontSize(14).fontWeight(FontWeight.Bold).fontColor(C.text).layoutWeight(1) Text(n.status).fontSize(10).fontColor(n.statusColor) .padding({ left: 6, right: 6, top: 3, bottom: 3 }) .backgroundColor(C.cardSoft).borderRadius(4) }.width(100%) Text(n.desc).fontSize(12).fontColor(C.textSub).maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis }) Text(n.time).fontSize(10).fontColor(C.textDim) }.alignItems(HorizontalAlign.Start).layoutWeight(1) }.width(100%) Row({ space: 8 }) { Text(进度).fontSize(10).fontColor(C.textDim) Progress({ value: n.progress, total: 100 }).color(C.primary).layoutWeight(1).height(6).borderRadius(3) Text(n.progress %).fontSize(10).fontColor(C.textDim) }.width(100%) } .width(100%).padding(12).backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke }) .onClick(() { promptAction.showToast({ message: n.title }); }) }4 条通知 比赛结果公布你的作品《樱花季》获得二等奖待查看橙进度 100% 精选通知你的作品被选为本周精选已查看灰100% 活动邀请摄影社邀你参加周末外拍待回复青绿50%⚙️ 系统维护今晚22:00-23:00系统维护已读灰100%NoticeCard 与 App 18 的差异多了一行进度条Row({ space: 8 }) { Text(进度).fontSize(10).fontColor(C.textDim) Progress({ value: n.progress, total: 100 }).color(C.primary).layoutWeight(1).height(6).borderRadius(3) Text(n.progress %).fontSize(10).fontColor(C.textDim) }进度条在通知卡里的语义活动邀请 50%——活动报名进行中进度 报名进度其他 100%——已处理完进度 处理进度通知进度条是 App 19 的特色——通知不只是看状态还带进度活动报名进度/处理进度——**通知 任务 进度**是协作/活动类 App 的通知范式钉钉的审批进度通知。进度标签 青绿进度条 百分比数字三通道——色弱用户也能读进度 50%文字 数字。4.2 ActivityCard互动动态卡本页核心Builder ActivityCard(a: ActivityItem) { Row({ space: 12 }) { Row() { Text(a.avatar).fontSize(28) } .width(48).height(48).backgroundColor(C.primarySoft).borderRadius(24).justifyContent(FlexAlign.Center) Column({ space: 4 }) { Row() { Text(a.name).fontSize(14).fontWeight(FontWeight.Bold).fontColor(C.text) Text( a.action).fontSize(12).fontColor(C.textSub) if (a.target.length 0) { Text( 「 a.target 」).fontSize(12).fontColor(C.primary).fontWeight(FontWeight.Bold) } Blank() Text(a.status).fontSize(10).fontColor(a.statusColor) .padding({ left: 6, right: 6, top: 2, bottom: 2 }) .backgroundColor(C.cardSoft).borderRadius(4) }.width(100%) Text(a.time).fontSize(10).fontColor(C.textDim) }.alignItems(HorizontalAlign.Start).layoutWeight(1) } .width(100%).padding(12).backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke }) .onClick(() { promptAction.showToast({ message: a.name a.action }); }) }4 条动态互动叙事 小明点赞了你的「校园日出」5分钟前新红 小美评论了你的「图书馆光影」1小时前已读灰 小华收藏了你的「樱花季」3小时前已读灰 小雪关注了你昨天新红小明 点赞了你的 「校园日出」式互动叙事是本页的核心设计——三段式文案Text(a.name).fontSize(14).fontWeight(FontWeight.Bold).fontColor(C.text) Text( a.action).fontSize(12).fontColor(C.textSub) if (a.target.length 0) { Text( 「 a.target 」).fontSize(12).fontColor(C.primary).fontWeight(FontWeight.Bold) }谁name 加粗— 小明做了什么action 灰色— 点赞了你的对什么target 青绿加粗 「」引号— 「校园日出」三段式互动叙事——谁 动作 对象是社交通知的标准文案微博/知乎XXX 赞了你的回答同款——**目标作品用青绿加粗 书名号强调**让用户一眼看到被互动的是哪个作品。动态状态新红/已读灰——新标注需要处理的互动。五、LikeList / CommentList按动作筛选LikeList点赞 Tab和 CommentList评论 Tab按动作类型过滤动态Builder LikeList() { Scroll() { Column({ space: 10 }) { ForEach(this.activities, (a: ActivityItem) { if (a.action.indexOf(点赞) 0 || a.action.indexOf(收藏) 0) { this.ActivityCard(a) } }, (a: ActivityItem) a.id.toString()) } ... } Builder CommentList() { Scroll() { Column({ space: 10 }) { ForEach(this.activities, (a: ActivityItem) { if (a.action.indexOf(评论) 0) { this.ActivityCard(a) } }, (a: ActivityItem) a.id.toString()) } ... }过滤条件用indexOf字符串匹配不是状态字段if (a.action.indexOf(点赞) 0 || a.action.indexOf(收藏) 0) {点赞 Tabaction.indexOf(点赞) 0 || action.indexOf(收藏) 0——点赞 收藏都算点赞类收藏也是喜欢信号评论 Tabaction.indexOf(评论) 0——评论单独一类indexOf 匹配的取舍优点简单直接无需额外字段缺点字符串匹配脆弱如果文案改成赞了就匹配不到、不语义化真实项目推荐动作类型枚举actionType: like | comment | followswitch过滤——**结构字段优于字符串匹配**是本系列反复强调的工程原则。App 19 用 indexOf 是 demo 简化读者应引以为戒。点赞 收藏归为点赞类是合理的产品决策——收藏也是赞用户收藏 喜欢的强烈信号。六、SystemList系统通知SystemList系统 Tab展示全部 4 条通知与 NoticeCard 同款Builder SystemList() { Scroll() { Column({ space: 10 }) { ForEach(this.notices, (n: NotifyItem) { this.NoticeCard(n) }, (n: NotifyItem) n.id.toString()) } .width(100%) .padding({ left: D.pad, right: D.pad, top: 12, bottom: D.pad this.safeBottom 20 }) } .layoutWeight(1).scrollBar(BarState.Off).align(Alignment.Top) }系统 Tab 通知全集4 条——系统通知是官方消息比赛/精选/活动/维护。4 个 Tab 的内容矩阵Tab动态通知卡片形态全部4 条4 条ActivityCard NoticeCard点赞2 条点赞/收藏—ActivityCard评论1 条评论—ActivityCard系统—4 条NoticeCard按 Tab 裁剪内容——点赞 Tab 只显示点赞/收藏动态、评论 Tab 只显示评论动态、系统 Tab 只显示通知——分类即视图。七、State 与辅助方法的克制Func2Tab 只有1 个 StatecurrentTab当前分类 0-3。过滤逻辑全部内联在 ForEach 的if里。1 个 State 驱动 4 个列表——currentTab一变 →if/else重渲染对应列表——状态驱动视图切换App 18 同款。辅助方法 0——indexOf过滤直接写在 ForEach 回调里简单条件内联。八、与 App 18 消息页的对比总结维度App 18 社交匹配消息App 19 校园影像社区Tab全部/未读/好友申请/系统全部/点赞/评论/系统统计未读/申请/互动/系统点赞/评论/粉丝/系统通知卡无进度条带进度条特色动态卡聊天卡互动叙事卡谁动作对象过滤unread0 / title 匹配action.indexOf 匹配特殊操作好友申请通过/忽略无纯通知App 19 的两个特色①通知进度条活动报名/处理进度②互动叙事三段式小明 点赞了你的 「校园日出」。4 分类通知中心模板已复用 2 次App 18/19。九、通知系统的状态机与已读语义App 19 的通知有 4 种状态待查看/已查看/待回复/已读背后是通知状态机新通知产生 → 待处理待查看/待回复统计 1 → 用户查看 → 已查看/已读统计 -14 条通知的状态分布 比赛结果公布待查看橙——有结果要去看 精选通知已查看灰——已看过 活动邀请待回复青绿——有邀请要回复⚙️ 系统维护已读灰——已读待查看/待回复是需要行动的通知橙/青绿高亮已查看/已读是处理完的灰——待处理 vs 已处理的颜色区分引导用户先处理待的通知。真实项目的通知状态机待处理 → 已处理查看/回复/操作后状态变更未读 → 已读打开通知列表自动标记新 → 旧时间排序App 19 的简化状态是静态的不会因点击变化——真实项目应点击通知 → 状态转已读 → 红点/角标消失与 App 18 的未读逻辑同理。已读语义是通知系统的核心——已读回执 未读计数驱动用户处理完通知。十、互动动态的数据模型App 19 的ActivityItem接口是社交通知的核心数据模型interface ActivityItem { id: number; avatar: string; name: string; action: string; target: string; time: string; status: string; statusColor: string; }8 个字段对应互动叙事的 8 要素字段语义示例id唯一标识1avatar互动者头像name互动者小明action互动动作点赞了你的target互动对象「校园日出」time时间5分钟前status状态新/已读statusColor状态色红/灰action 是动词短语点赞了你的/评论了你的/收藏了你的/关注了你——动作文案 对象拼接成完整句子小明 点赞了你的 「校园日出」。真实项目的 ActivityItem 应加actionType: like | comment | follow结构化动作替代字符串匹配userId跳转互动者主页postId跳转被互动作品isRead: boolean已读状态互动数据模型是社交通知的核心——App 19 的 8 字段是精简版真实项目在此基础上加类型枚举 跳转 id 已读状态。十一、通知进度条的 3 种语义App 19 通知卡的进度条Progress在不同通知里有不同语义这是同组件多语义的示例1. 活动邀请 50%——活动报名进度50% 报名进行中——进度 活动状态报名满 100% 活动开始2. 比赛结果 100%——处理进度100% 已出结果——进度 事件完成度3. 其他通知 100%——信息完整度100% 消息已完整——进度 内容完整性50% vs 100%的对比设计——只有活动邀请是 50%未完成状态其他都是 100%完成状态——50% 的邀请需要行动、100% 的通知已完结——进度条 待办信号50% 的邀请提醒用户还要去报名。真实项目的通知进度条应用审批流请假审批 30% → 60% → 100%众筹/拼团进度 65% 还差 X 人任务系统每日任务 2/5通知 进度是活动/任务类通知的进阶——普通通知App 18只显示状态文字进阶通知App 19加进度条让完成度可视化。50% 的视觉心理——半截进度条比待回复三个字更有紧迫感用户看到 50% 会想还差一半就满了——进度条是更生动的状态表达。十二、总结App 19 社区互动页解析完毕。4 分类真切换 通知进度条 互动叙事三段式 点赞/评论按动作筛选是四大亮点。谁 动作 对象的互动文案是社交通知的标准范式**通知带进度**是活动类通知的进阶设计。