鸿蒙原生应用实战:HarmonyOS 6.0下,表白墙互动页赞/评论/回复三分段消息流

App 41「校园表白墙」互动页(Func2Tab),主题色 #FF4757 红色(red),4 个 Tab 分别为首页(💌)、发布(✍️)、互动(💬)、我的(👤)。互动页采用"Header + 消息流"两区布局——白色双行 Header("互动消息"20 号加粗 + "收到的赞 / 评论 / 回复"三分段,选中紫色加粗) + 4 条互动消息(❤️ 赞了你的表白 / 💬 评论了你 / ❤️ 赞了你的评论 / ↩️ 回复了你,每条含 42×42 浅红圆形 emoji 图标 + "匿名同学 + 动作类型 + 时间"三行头 + 单行摘要 + 缩进 Divider 分隔)。每条消息展示"谁 + 做了什么 + 内容摘要 + 何时",点击弹动作类型 Toast。本篇基于 41-confession-wall/entry/src/main/ets/pages/Func2Tab.ets(共 87 行)逐段拆解,附 4 张实机截图。

一、整体结构:两区"Header + 消息流"布局

互动页是"品牌头部 + 消息列表"的两区布局:

build() {
  Column() {
    this.Header()
    Scroll() {
      Column({ space: 0 }) {
        this.List()
      }
      .width('100%').padding({ bottom: D.pad + this.safeBottom + 20 })
    }
    .layoutWeight(1).scrollBar(BarState.Off).align(Alignment.Top)
  }
  .width('100%').height('100%').backgroundColor(C.bg)
}

2 块结构:

  1. Header — 双行结构:标题行 + 三分段行,白底固定
  2. List — 4 条互动消息,space: 0(列表内由 Divider 分隔而非间距)

本页是"消息通知"类页面——与首页帖子流的"卡片悬浮"风格不同,互动页采用"整行白底 + Divider 分隔"的列表风格,视觉上更像系统通知(微信消息列表),语义上区分"浏览内容"与"查看通知"两种模式。

41 互动页首屏

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

二、Header:标题 + 三分段

Header() {
  Column() {
    Row() { Text('互动消息').fontSize(20).fontWeight(FontWeight.Bold).fontColor(C.text) }
    .width('100%').height(this.safeTop + 52).padding({ top: this.safeTop, left: D.pad, right: D.pad })
    .alignItems(VerticalAlign.Bottom)
    Row() {
      ForEach(this.tabs, (t: string, idx: number) => {
        Text(t).fontSize(14)
          .fontColor(this.tab === idx ? C.primary : C.textSub)
          .fontWeight(this.tab === idx ? FontWeight.Bold : FontWeight.Normal)
          .layoutWeight(1).textAlign(TextAlign.Center).padding({ bottom: 12 })
          .onClick(() => { this.tab = idx; })
      }, (t: string) => t)
    }.width('100%')
  }.width('100%').backgroundColor(C.card)
}

技术拆解:

  1. 标题行:"互动消息"20 号加粗、safeTop + 52 高度、底部对齐——与 App 40 活动页同款。
  2. 三分段:['收到的赞', '评论', '回复'] 三个分类——对应互动动作的三种类型:点赞、评论、回复。每个 Text layoutWeight(1) 平分、居中、padding({ bottom: 12 }) 与内容区留距。
  3. 选中态:@State tab: number 驱动,选中红色加粗、未选灰色常规——与首页"最新/最热"的指示条不同,本页用"纯文字变色"(更轻),两种分段风格在 App 内并存,各有适用场景。
  4. received 语义:"收到的赞"而非"点赞"——本页展示的是"别人对我的互动",是通知视角而非操作视角,措辞精确。

三、List:互动消息流

List() {
  Column() {
    ForEach(this.items, (it: Interaction, idx: number) => {
      Row({ space: 12 }) {
        Row() { Text(it.emoji).fontSize(20) }
        .width(42).height(42).backgroundColor(C.primarySoft).borderRadius(21).justifyContent(FlexAlign.Center)
        Column({ space: 4 }) {
          Row() {
            Text('匿名同学 ').fontSize(13).fontWeight(FontWeight.Medium).fontColor(C.text)
            Text(it.type).fontSize(13).fontColor(C.textSub).layoutWeight(1)
            Text(it.time).fontSize(11).fontColor(C.textDim)
          }.width('100%')
          Text(it.content).fontSize(12).fontColor(C.textDim).maxLines(1)
            .textOverflow({ overflow: TextOverflow.Ellipsis }).width('100%')
        }.alignItems(HorizontalAlign.Start).layoutWeight(1)
      }
      .width('100%').padding({ left: D.pad, right: D.pad, top: 14, bottom: 14 }).backgroundColor(C.card)
      .onClick(() => { promptAction.showToast({ message: it.type }); })
      if (idx < this.items.length - 1) {
        Divider().color(C.stroke).strokeWidth(0.5).margin({ left: D.pad + 54 })
      }
    }, (it: Interaction) => it.id.toString())
  }.width('100%')
}

互动消息数据(22-27 行)由 private items: Interaction[] 静态数组提供:

emoji动作类型内容摘要时间
❤️赞了你的表白图书馆三楼靠窗的女生...5分钟前
💬评论了你好浪漫呀,祝你成功!15分钟前
❤️赞了你的评论同感,那个学长确实优秀1小时前
↩️回复了你谢谢你的祝福 😊2小时前

消息行细节:

  1. 图标:42×42 浅红圆底 + 20 号 emoji——❤️(赞)、💬(评论)、↩️(回复),emoji 即动作类型图标,一眼可辨。
  2. 头行三信息:"匿名同学 " 13 号 Medium + it.type 13 号灰色(layoutWeight(1) 撑开)+ it.time 11 号浅灰——"谁 + 做了什么 + 何时"一行排布,信息密度高。
  3. 摘要行:12 号浅灰、maxLines(1) + textOverflow(Ellipsis) 单行省略——消息内容过长时截断,保持列表整洁(对比首页帖子的全文展示,通知场景只需摘要)。
  4. 缩进 Divider:.margin({ left: D.pad + 54 })——分隔线从"图标右缘"开始缩进 54 像素,左边距对齐图标右侧而非整行开头,这是微信式消息列表的标志性细节:分隔线不贯穿图标列,避免割裂感。
  5. 整行可点:点击 Toast 动作类型("赞了你的表白")。
  6. key:it.id.toString() 稳定唯一。

四、跨页数据自洽:互动页是首页动作的"通知中心"

互动页与首页的数据严格对应:

  • 第一条"赞了你的表白 / 图书馆三楼靠窗的女生..." ↔ 首页第一帖正文(图书馆三楼靠窗的女生,你看书认真的样子真好看...)——内容摘要一致,说明"赞"是对首页帖子的真实点赞动作。
  • 第二条"评论了你 / 好浪漫呀,祝你成功!" ↔ 首页第一帖的评论区(Demo 未展示评论区,但评论内容与表白主题呼应)。
  • 第三条"赞了你的评论":点赞的层级从"帖子"延伸到"评论",互动模型更立体。
  • 第四条"回复了你 / 谢谢你的祝福 😊" ↔ 第二条"评论了你"的后续——评论 → 回复构成对话链。
  • 时间梯度:5分钟/15分钟/1小时/2小时与首页帖子时间同梯度,模拟真实时间流。
  • 我的页"💬 互动消息"菜单 ↔ 本页 Header"互动消息"——菜单即本页入口,命名一致。

五、实机截图与交互演示

本节结合 4 张实机截图,逐张还原互动页的视觉效果与交互过程。

1. 互动页首屏:三分段 + 消息流

第一张截图是互动页默认首屏:顶部"互动消息"标题,下方"收到的赞 / 评论 / 回复"三分段——"收到的赞"为红色加粗选中态;下方是 4 条互动消息——❤️ 赞了你的表白(5分钟前)、💬 评论了你(15分钟前)、❤️ 赞了你的评论(1小时前)、↩️ 回复了你(2小时前),每条含 42×42 浅红圆底 emoji 图标、三行头信息与单行摘要,Divider 缩进分隔清晰可见。

2. 点击"评论":分段切换

第二张截图是点击"评论"分段后的状态:红色加粗高亮从"收到的赞"切换到"评论",@State tab 由 0 变 1。Demo 三分段共用同一消息列表(未按类型过滤),但分段切换交互完整,为"按动作类型过滤消息"预留了结构——真实产品 tab === 0 过滤 type='赞'、tab === 1 过滤 type='评论'。

3. 点击消息:弹出动作类型 Toast

第三张截图是点击第一条消息(❤️ 赞了你的表白)后的反馈:弹出"赞了你的表白"Toast。整行可点、闭包捕获 it.type——点击哪条消息就弹出哪个动作类型,列表点击参数传递正确。

4. 互动页完整列表:四消息全览

第四张截图是互动页的完整列表视图:四条消息全部可见,缩进 Divider(从图标右侧缩进)在消息间清晰分隔,最后一条(↩️ 回复了你)之后无 Divider。整个列表"整行白底 + 细线分隔"的通知风格一览无余,Scroll 滚动流畅,底部安全区内边距保证 Tab 栏可点。

六、扩展思考:消息通知系统的完整设计

互动页是"通知中心"的最小原型,真实产品的通知系统复杂得多:

  1. 通知类型扩展:除赞/评论/回复外,还有"关注了你""提到了你""新粉丝"等类型——Interaction 接口的 type 字段可扩展,UI 按 type 映射 emoji 图标(当前 4 类已示范映射表模式)。
  2. 未读标记:每条消息应有"已读/未读"状态——未读消息加红点角标或底色高亮(系列 App 38 交流页已示范红点角标),已读后置灰。@State read: boolean 字段驱动。
  3. 点击跳转:点击消息应跳转到"对应的帖子/评论"——如点"赞了你的表白"跳到首页第一帖定位——需要消息携带 postId 引用,App 38 交流页的数据引用模式可复用。
  4. 通知聚合:同帖子的多条赞可聚合为"N 个人赞了你的表白"(点开看明细),避免通知刷屏——消息列表的"聚合/展开"是通知产品的进阶能力。
  5. 推送接入:真实产品通过鸿蒙推送(@ohos.push)把互动事件实时推到通知栏,App 打开后同步到本页——本页是推送消息的 App 内落点。

七、扩展思考:消息列表的交互与信息设计

  1. 缩进 Divider 的对齐价值:margin({ left: D.pad + 54 }) 让分隔线对齐图标右侧(42 宽图标 + 12 间距 = 54)——视觉上"图标列完整、内容列分隔",这是微信/QQ 消息列表的通用细节,用户无意识中感受到的"精致"往往来自这类对齐。
  2. 摘要行的取舍:maxLines(1) + 省略号让长内容一行收起——通知场景用户只看"是什么事",详情点击进入。与首页帖子全文展示形成"列表摘要 vs 内容全文"的信息分层。
  3. 时间倒序:5分钟 → 2小时的时间梯度暗示列表按时间倒序(最新在前)——通知列表的标准排序。
  4. 空态设计:若互动消息为空(新用户无互动),应显示"还没有人给你点赞"空态图 + 引导"去首页逛逛"——当前 4 条静态数据演示不了空态,产品化必备。
  5. 左右滑动操作:消息行支持左滑"删除/标记已读"(SwipeAction 组件)是移动端通知的常见交互——扩展方向明确。

41 互动页完整列表

八、开发者视角:互动页的调试与验证技巧

  1. 缩进 Divider 的像素对齐:D.pad + 54 中 54 = 42(图标宽)+ 12(Row space)——若改图标尺寸,缩进值必须同步更新,否则分隔线错位。调试时用截图 + 标尺核对。
  2. maxLines 生效条件:textOverflow({ overflow: TextOverflow.Ellipsis }) 必须配 maxLines(1) 与 width('100%') 三件套——缺一省略号不显示(与 App 40 首页同款坑)。
  3. 分段过滤测试:若实现"按类型过滤",需分别验证三个分段下列表长度与内容——items.filter(it => it.type === '赞了...') 的匹配逻辑要注意 type 文案精确匹配。
  4. 消息点击的闭包:onClick 闭包捕获 it——ForEach 的 key 必须稳定(id),否则重排后点击会捕获错位的 item(经典闭包陷阱)。
  5. 长列表性能:消息可能成百上千条,ForEach 应升级 LazyForEach + 固定行高(height 常量),保证滚动流畅——当前 4 条静态数据无压力。

九、系列横向对比:列表页 Divider 的四种用法

互动页的缩进 Divider 是系列中处理最精细的,横向对比可看清 Divider 的完整用法谱系:

Divider 用法代表页实现视觉效果
缩进分隔App 41 互动页margin 左缩进 54图标列完整、内容列分隔
全宽细线App 41/40 我的页菜单无 margin标准菜单分隔
条件分隔系列所有菜单idx 判断最后一行最后一项无分隔线
无 DividerApp 41 首页帖子space 间距卡片悬浮感

缩进 vs 全宽的语义:互动页是"消息列表"(微信式),用缩进 Divider 营造"头像列连续、内容列分隔"的层次;我的页菜单是"功能清单"(设置式),用全宽 Divider 明确"每行是一个独立入口"。Divider 的缩进程度决定列表的"社交感 vs 工具感"——缩进越多越像聊天 App,全宽越像设置页。本页 54 像素的缩进(42 图标 + 12 间距)正是微信消息列表的标准对齐,细节处见专业。

为什么本页不用卡片间距:首页帖子用"卡片 + space 间距"(内容需要悬浮突出),互动页用"整行 + Divider"(通知需要紧凑高效)——内容型列表用卡片、通知型列表用分隔线,这是两类列表的视觉分水岭。App 41 同一 App 内两种风格并存且各自合理,说明列表形态选择始终服务于"内容属性"而非"风格统一"。

41 互动页消息 Toast

十、系列横向对比:消息通知页的三种形态

互动页是"通知中心"的轻量实现,系列其他 App 的通知/消息能力可对照:

通知形态代表 App能力复杂度
互动消息流App 41 互动页赞/评论/回复通知轻
聊天会话列表App 38 交流页私聊会话 + 未读角标中
提醒事项App 27 提醒页日历 + 提醒列表中

App 41 互动页是系列首个"被动通知"页面(别人对你做了什么),而 App 38 交流页是"主动聊天"——两者构成社交产品的两大通知维度:互动通知(赞/评论)与消息会话(私聊)。真实产品中二者会合并进同一个"消息中心"(顶部 Tab 切换"互动/私信"),本页的三分段结构(收到的赞/评论/回复)正是这种合并的雏形。

通知的点击闭环:App 41 互动消息点击弹 Toast(占位),App 38 交流消息点击也应进入聊天页——产品化后两个页面的消息都应携带目标引用(postId/会话 id)跳转,把"通知"转化为"行为"。通知页的最高境界是"每一条都能点进去看到上下文",本页与 App 38 的点击占位均为这一闭环留好了接口。

41 互动页评论分段

十一、开发者视角:互动页的常见问题与避坑清单

  1. 缩进 Divider 的维护成本:margin({ left: D.pad + 54 }) 中 54 与图标尺寸(42)强耦合——若设计师调整图标为 48,缩进必须同步改为 60,否则分隔线错位。建议把 54 定义为常量(如 const DIVIDER_INDENT = D.pad + 54)集中管理。
  2. 消息去重的必要性:真实通知可能有重复(同一人多次点赞)——列表应去重聚合("匿名同学 和另外 3 人赞了你"),否则用户被同一类通知刷屏。聚合逻辑通常在服务端完成,客户端只渲染聚合结果。
  3. 时间格式的刷新:5分钟前/1小时前 这类相对时间是"活的"——页面停留 10 分钟后"5分钟前"应变为"15分钟前",需要定时刷新或进入页面时重新计算。Demo 静态时间可接受,产品化需 setInterval 或 onPageShow 重算。
  4. 点击跳转的上下文:点击"赞了你的表白"应跳转到被赞的帖子——消息数据需携带 postId,跳转后帖子高亮定位。当前 Toast 占位丢失了"上下文"信息,产品化时要补上。
  5. 未读红点的数据源:若加未读标记(App 38 已示范红点角标),未读数应来自服务端统一统计,互动页 Tab 图标与菜单项(我的页"💬 互动消息")同步显示——红点数据全 App 一致,避免"这里读了那里还亮"的矛盾。

十二、FAQ 与一句话总结

Q1:互动页和首页帖子是什么关系? 互动页是首页互动动作的"通知回执"——你在首页点赞的帖子,作者会在互动页收到"有人赞了你的表白";反过来,别人对你的互动也汇总在这里。两页是"动作发生地"与"通知接收地"的关系。

Q2:为什么用"收到的赞"而不是"点赞"? "收到的赞"明确是"别人给我的"(被动),"点赞"是"我给的"(主动)——本页展示的是别人对我的互动,措辞必须区分方向,避免语义混淆。

Q3:缩进 Divider 有什么好处? 分隔线从图标右缘开始,图标列保持完整连续——视觉上降低"割裂感",让列表更接近真实消息 App 的质感,是细节处的专业度。

Q4:点击消息为什么弹的是动作类型? Demo 未实现跳转,用动作类型 Toast 占位最贴语义。产品化后点击应携带 postId 跳转到对应帖子,Toast 换成路由跳转即可。

Q5:三分段为什么不真的过滤消息? Demo 为演示简洁共用列表。真实产品按 type 过滤(收到的赞只显示赞类),@State tab 已就绪,过滤逻辑一行动态筛选即可——结构上零改动。

一句话总结:互动页用"三分段 + 消息流"完成了通知中心的范式——emoji 图标即动作类型、三行头信息即"谁/什么/何时"、缩进 Divider 即列表精致感、单行摘要即信息分层。配合首页点赞的真实联动("赞了你的表白"引用首页第一帖),互动页让整个 App 的"动作 → 通知"闭环真实可信,是系列中完成度最高的通知类页面。

最后从验收视角确认:四张实机截图覆盖了首屏(分段+消息流)、分段切换(评论高亮)、消息点击(动作 Toast)、完整列表(四消息全览)四个状态,缩进 Divider 的对齐、单行摘要的省略、整行点击的反馈均验证正常,配合首页点赞的真实联动数据,互动页的"通知中心"职能完整落地,验收通过。 未来若接入推送与未读红点,互动页即可无缝升级为生产级的消息中心,当前三分段结构已为此预留全部扩展点。 再看互动页在整个 App 中的位置:首页负责"表达",发布页负责"生产",互动页负责"回响"——用户的每一份心意在这里得到反馈,这种"表达必有回响"的设计正是社交产品留住用户的情感纽带,也是本页虽小却至关重要的原因。而缩进 Divider、单行摘要、emoji 图标这些细节,则让"回响"的呈现足够精致——用户在意的是心意被认真对待,页面的每一处考究都在传递这份认真。 补充说明:互动页的交互设计还有一处容易被忽略的细节——每条消息整行可点且 Toast 反馈动作类型,这个"点击即反馈"的模式其实已经隐含了"消息可操作"的心理暗示,用户会自然期待点击后看到更多内容,这正是产品化后跳转帖子的行为基础。另外,消息行的 space: 0 与 Divider 搭配,让列表在"紧凑与分隔"之间取得平衡——不靠间距靠细线,是通知列表区别于内容卡片的典型手法。 互动页虽然只有 87 行代码,却示范了通知类列表页的全部要点:消息模型(Interaction)、图标映射(emoji 即类型)、三行头信息(谁/什么/何时)、单行摘要(省略号)、缩进分隔(Divider)、分段筛选(@State tab)——这套"消息列表六件套"可直接复用到任何通知中心、站内信、私信列表场景,值得开发者反复研读。

配图

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐