鸿蒙原生应用实战:用 ArkUI 搭纪念册首页 —— Banner 与纪念册列表
App 44「校园纪念册」首页(HomeTab),主题色
#A29BFE淡紫色(lavender),4 个 Tab 分别为首页(📔)、相册(📸)、留言(💬)、我的(👤)。首页采用"Header + Banner + 纪念册列表"三区布局——白色双行 Header("校园纪念册"22 号加粗 + "记录我们共同的青春 📔")+📔 渐变 Banner("创建你的纪念册" + "邀请同学一起添加照片和留言")+SectionTitle(我的纪念册 + 全部 >)+ 4 本纪念册列表(🎓 计科2022级毕业纪念 / 🏫 软件工程班级相册 / 🎊 社团年度纪念册 / ⛰️ 大三秋游纪念,每本含 80×90 淡紫封面图块 + 标题 + 📷 N 张 + 👥 N 人 + 淡紫"查看纪念册 >")。本篇基于44-memorial-book/entry/src/main/ets/pages/HomeTab.ets(共 101 行)逐段拆解,附 4 张实机截图。
一、整体结构:三区"Header + Banner + 纪念册列表"布局
首页是"品牌头部 + 创建引导 + 纪念册清单"的三区布局——3 个 @Builder 块:
build() { Column() { this.Header() Scroll() { Column({ space: 16 }) { this.Banner() this.SectionTitle('我的纪念册') this.BookList() } .width('100%') .padding({ left: D.pad, right: D.pad, top: 14, bottom: D.pad + this.safeBottom + 20 }) } .layoutWeight(1).scrollBar(BarState.Off).align(Alignment.Top) } .width('100%').height('100%').backgroundColor(C.bg) }3 块结构:
- Header— 双行品牌头(标题 + 副标题),白底固定
- Banner— 📔 渐变宣传卡,"创建你的纪念册"是产品的主 CTA(Call To Action)
- BookList— "我的纪念册" + 4 本纪念册列表,是用户的核心资产展示
首页没有分类筛选、没有瀑布流——纪念册是"少而珍贵"的资产(一个班级就几本),用单列大卡列表展示最合适:每本纪念册有封面、标题、数据(照片数/人数)、入口,信息完整且庄重,符合"纪念册"的产品气质(与 App 40 相册瀑布流的"多而密"形成对照)。
项目源码开源:https://gitee.com/codenestFlow/HarmonyOSHub
二、Header:双行品牌头
Header() { Column() { Text('校园纪念册').fontSize(22).fontWeight(FontWeight.Bold).fontColor(C.text) .width('100%').padding({ top: this.safeTop + 10, left: D.pad, right: D.pad, bottom: 4 }) Text('记录我们共同的青春 📔').fontSize(12).fontColor(C.textDim).width('100%') .padding({ left: D.pad, right: D.pad, bottom: 12 }) }.width('100%').backgroundColor(C.card) }细节:
- 标题:"校园纪念册"22 号加粗,直白点题(班级/校园的集体记忆)。
- 副标题:"记录我们共同的青春 📔"——"共同的青春"强调集体属性(纪念册是大家的,不是个人的),📔 纪念册 emoji 呼应产品形态。
- 安全区:
safeTop + 10避让状态栏,双行间距层次清晰。 - 白底全宽:系列双行 Header 范式(App 39/42/43 同款)。
三、Banner:📔 渐变创建引导卡
Banner() { Row({ space: 12 }) { Text('📔').fontSize(40) Column({ space: 4 }) { Text('创建你的纪念册').fontSize(16).fontWeight(FontWeight.Bold).fontColor('#FFFFFF') Text('邀请同学一起添加照片和留言').fontSize(12).fontColor('#FFFFFF').opacity(0.9) }.alignItems(HorizontalAlign.Start).layoutWeight(1) } .width('100%').padding(18).borderRadius(D.rLg) .linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] }) .onClick(() => { promptAction.showToast({ message: '创建纪念册' }); }) }技术拆解:
- 大图标 + 双行文案:40 号 📔 视觉锚点 + 16 号加粗"创建你的纪念册"(主 CTA)+ 12 号 90% 透明度"邀请同学一起添加照片和留言"(功能说明)。
- CTA 语义:Banner 不是"宣传"而是"引导创建"——整卡
onClick弹"创建纪念册"Toast,产品化后进入"新建纪念册"流程(填标题 → 邀请同学 → 开始记录),是产品增长的入口。 - 渐变背景:
linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] })从淡紫#A29BFE到浅淡紫#C4BEF5——比 App 40/42 的紫色更"淡",契合纪念册"温柔怀旧"的氛围。 - 布局弹性:右侧 Column
layoutWeight(1)撑开,左图标固定,任何屏宽排版稳定。
四、BookList:纪念册列表
BookList() { Column({ space: 14 }) { ForEach(this.books, (b: Book) => { Row({ space: 14 }) { Column() { Text(b.emoji).fontSize(40) } .width(80).height(90).backgroundColor(C.primarySoft) .borderRadius(D.rMd).justifyContent(FlexAlign.Center) Column({ space: 8 }) { Text(b.title).fontSize(16).fontWeight(FontWeight.Bold).fontColor(C.text).maxLines(2) .textOverflow({ overflow: TextOverflow.Ellipsis }) Row({ space: 14 }) { Text('📷 ' + b.photos + ' 张').fontSize(12).fontColor(C.textDim) Text('👥 ' + b.members + ' 人').fontSize(12).fontColor(C.textDim) } Text('查看纪念册 >').fontSize(12).fontColor(C.primary) }.alignItems(HorizontalAlign.Start).layoutWeight(1) } .width('100%').padding(14).backgroundColor(C.card).borderRadius(D.rLg).border({ width: 1, color: C.stroke }) .onClick(() => { promptAction.showToast({ message: b.title }); }) }, (b: Book) => b.id.toString()) }.width('100%') }4 本纪念册(20-25 行):
| 纪念册 | emoji | 照片 | 成员 |
|---|---|---|---|
| 计科2022级毕业纪念 | 🎓 | 256 | 45 |
| 软件工程班级相册 | 🏫 | 189 | 38 |
| 社团年度纪念册 | 🎊 | 320 | 60 |
| 大三秋游纪念 | ⛰️ | 128 | 42 |
卡片细节:
- 封面图块:80×90 淡紫底 + 40 号 emoji(🎓 毕业 / 🏫 校园 / 🎊 社团 / ⛰️ 秋游)——比 App 40 相册封面更高的图块(90 高),"封面感"更强;emoji 即纪念册主题的视觉符号。
- 标题:16 号加粗,
maxLines(2)+ 省略号防超长标题换行撑破("计科2022级毕业纪念"这类长标题两行内可容)。 - 数据行:
📷 N 张+👥 N 人12 号浅灰——照片量(内容规模)+ 成员数(参与广度)是纪念册的两大数据维度,用户据此判断"哪本值得先看"。 - 查看入口:12 号淡紫"查看纪念册 >"——颜色与 Banner 渐变呼应,暗示可点击进入纪念册详情。
- 整卡点击:点击 Toast 纪念册标题,产品化后进入纪念册详情页(照片墙 + 留言墙)。
- key:
b.id.toString()稳定唯一。
五、跨页数据自洽:纪念册贯穿三页
首页的纪念册与相册、留言、我的页形成完整体系:
- 首页 4 本纪念册↔ 我的页"4 纪念册"统计、副标题"参与 4 本纪念册"——数字完全一致,4 本即用户参与的全部纪念册。
- 相册页 8 张照片↔ 首页"📷 N 张"中的相册内容——首页"计科2022级毕业纪念"的 256 张照片即相册页的"班级相册"(8 张是展示样例,256 是总数口径)。
- 留言页"毕业寄语"↔ 纪念册的留言功能——首页 Banner"邀请同学一起添加照片和留言"中的"留言"即留言页的寄语。
- 我的页"86 我的照片 / 12 我的留言"↔ 相册页照片 + 留言页留言——个人贡献的累计统计。
六、实机截图与交互演示
本节结合 4 张实机截图,逐张还原首页的视觉效果与交互过程。
1. 首页首屏:品牌头 + 创建 Banner + 纪念册
第一张截图是进入 App 44 后的默认首屏:顶部"校园纪念册"标题与"记录我们共同的青春 📔"副标题;下方淡紫渐变 Banner——📔 大图标 + "创建你的纪念册" + "邀请同学一起添加照片和留言";再往下是"我的纪念册 全部 >"标题行与第一本纪念册卡(🎓 计科2022级毕业纪念 / 📷 256 张 / 👥 45 人 / 查看纪念册 >),第二本(🏫 软件工程班级相册)部分可见。淡紫主题温柔怀旧,Banner 的创建引导明确。
2. 点击 Banner:创建纪念册 Toast
第二张截图是点击淡紫渐变 Banner 后的反馈:弹出"创建纪念册"Toast。整卡挂载onClick,点击任意区域(📔 图标/标题/说明)都触发同一反馈——"创建纪念册"是产品的主 CTA,Banner 的整卡可点设计最大化引导转化。
3. 点击纪念册:弹出标题 Toast
第三张截图是点击第一本纪念册卡(🎓 计科2022级毕业纪念)后的反馈:弹出"计科2022级毕业纪念"Toast。每本纪念册独立挂载onClick且闭包捕获各自的b.title,点击哪本就弹出哪本——列表点击参数传递正确。
4. 滚动到底:四本纪念册完整可见
第四张截图是滚动到底部的视图:第三本"🎊 社团年度纪念册"(320 张 / 60 人)与第四本"⛰️ 大三秋游纪念"(128 张 / 42 人)完整可见。四本纪念册按"毕业/班级/社团/秋游"覆盖大学四年与校园生活的不同场景,Scroll 滚动流畅,底部安全区内边距保证 Tab 栏可点。
七、扩展思考:纪念册的产品形态与社交属性
首页 4 本纪念册揭示了这个产品的独特定位:
- 集体记忆 vs 个人相册:纪念册是"集体的"——每本有成员数(45 人/38 人),照片和留言由多人共同贡献(Banner"邀请同学一起添加"),这与 App 40 个人照片共享(个人上传)本质不同:纪念册是"共写一本书",照片墙是"各发各的"。
- 生命周期:纪念册伴随一个群体的一段时光(毕业/班级/社团/秋游)——有明确的"主题 + 时间窗",与 App 40 活动的关联类似但更长期(纪念册存续多年,活动有起止)。
- 创建与邀请:创建纪念册(Banner CTA)→ 邀请同学加入 → 共同添加照片和留言——邀请机制是纪念册的社交裂变点,一本纪念册 = 一个群的共同记忆容器。
- 数据维度:照片数(内容量)+ 成员数(参与度)双维度展示——用户点开前就能感知"这本册子多厚、多少人参与",是集体资产的"厚度可视化"。
- 纪念册 vs 相册 Tab 的关系:首页是"册子目录"(多本纪念册),相册 Tab 是"当前册子的照片墙"——目录 + 内容两级结构,点击首页的册子进入相册 Tab 对应的照片集。
八、扩展思考:纪念册详情页的产品设计
首页纪念册点击后(当前 Toast)应进入详情页,其设计可参考成熟产品:
- 详情页信息架构:封面大图 + 册名 + 成员头像墙(45 个头像环形排布)+ 数据(照片数/留言数)+ 两个页签(照片墙 / 留言墙)+ 加入按钮。
- 成员墙:展示参与同学的头像(emoji 头像可复用系列风格),点击查看该同学在册中的贡献——成员的在场感是纪念册区别于普通相册的核心。
- 时间线浏览:照片按时间线组织(大一军训 → 大四毕业),提供"回忆时间轴"滑动浏览——纪念册是"时光的书",时间线是翻书的方式。
- 共同编辑:成员可上传照片(相册 Tab)、写留言(留言 Tab)——协作文档式的纪念册,多人共同维护,是产品的核心机制。
- 导出与实体化:纪念册可导出 PDF / 生成电子纪念册 H5 分享,甚至对接实体打印(把电子纪念册印成纸质册子)——纪念册的"可打印"属性是独特价值。
九、开发者视角:首页的调试与验证技巧
- 长标题的省略:
maxLines(2)+ Ellipsis + 明确宽度三件套——"计科2022级毕业纪念"这类长标题在卡片内两行可容,验证更长标题(如"计算机科学与技术2022级1班毕业纪念册")的省略位置。 - 封面图块的对齐:80×90 封面 + 40 号 emoji 垂直居中(
justifyContent(FlexAlign.Center))——若 emoji 在部分字体下偏高,会与数据行错位,真机验证。 - Banner 的点击热区:整卡
onClick覆盖全宽——确认文字区与图标区都可点,无"点了没反应"的边界。 - 数据自洽回归:首页 4 本纪念册 ↔ 我的页"4 纪念册"——修改任意一处需同步(最好抽公共常量),系列验收标准。
- 列表性能:纪念册数量有限(一个班级几本),
ForEach足够;若未来支持"广场"(全校纪念册),需LazyForEach分页。
十、系列横向对比:集体记忆类产品 vs 个人内容产品
App 44 是"集体记忆类产品",与系列的个人内容产品对比可看清其设计差异:
| 维度 | App 44 纪念册 | App 40 相册 | App 41 表白墙 |
|---|---|---|---|
| 内容主体 | 集体(班级/社团) | 个人 | 个人(匿名) |
| 组织单位 | 纪念册(多人共享) | 相册(个人) | 帖子 |
| 核心数据 | 照片数+成员数 | 照片数 | 点赞数 |
| 参与方式 | 邀请共同编辑 | 个人上传 | 个人发布 |
| 情感基调 | 怀旧、共同记忆 | 记录、分享 | 表达、心动 |
纪念册的差异:首页每本纪念册都有"👥 成员数"(45 人/38 人)——这是个人产品没有的维度;Banner"邀请同学一起添加"直接点明协作属性(纪念册是多人共同维护的,不是单方面展示)。App 40 相册是"我分享给大家看"(个人 → 平台),纪念册是"我们一起写一本书"(集体 ↔ 集体)——内容主体从"我"变成"我们",是整个 App 设计逻辑的根本转变:成员数替代获赞数成为核心指标、创建+邀请替代上传成为核心动作。
共享的骨架:尽管主体不同,首页仍复用系列"双行 Header + 渐变 Banner + 内容列表"的骨架——品牌区、CTA、内容区三层结构在个人与集体产品间通用,再次验证了系列方法论的普适性。
十一、扩展思考:纪念册的创建与邀请流程
首页 Banner"创建你的纪念册"是产品增长的核心入口,其完整流程值得展开:
- 创建向导:点击 Banner → 填写册名(默认"XX 班级纪念册")→ 选择主题(毕业/班级/社团/旅行,对应首页 4 类)→ 生成封面(emoji 自选或上传照片)——三步完成创建。
- 邀请机制:创建后生成邀请码/链接,分享到班级群——同学点击加入后自动成为成员(成员数 +1),邀请裂变是纪念册的增长引擎(一本册子 = 一个群的转化)。
- 成员权限:创建者为管理员(可审核照片/删除留言/转让),成员可上传照片与留言——权限分层是集体产品的内容治理基础。
- 创建后的引导:新册子空态引导"上传第一张照片""写下第一条寄语"——冷启动引导让纪念册"从零开始"时不冷清。
- 与相册/留言的衔接:创建成功后进入纪念册详情页,相册 Tab 与留言 Tab 绑定该册子——首页的"册子"与 Tab 的"内容"在此打通。
十二、FAQ 与一句话总结
Q1:纪念册和普通相册(App 40)有什么区别?纪念册是"集体共写"——一本册子有成员、有共同主题(毕业/班级)、多人共同添加照片和留言;相册是"个人共享"——个人上传、平台聚合。首页的"👥 45 人"与"邀请同学一起添加"直接体现了集体属性。
Q2:为什么首页没有分类或瀑布流?纪念册是"少而珍贵"的资产(一个用户参与几本),单列大卡列表能完整展示封面、标题、数据与入口,庄重清晰;瀑布流适合"多而密"的照片浏览(相册 Tab 已是 3 列网格)。内容形态决定列表形态。
Q3:"创建你的纪念册"Banner 点击后去哪?Demo 弹 Toast 占位。产品化后进入"新建纪念册"向导:填标题 → 选主题(毕业/班级/社团)→ 邀请同学 → 创建成功进入详情页——Banner 是产品增长的主入口。
Q4:4 本纪念册的数据从哪来?静态数组模拟"用户参与的纪念册"——与我的页"4 纪念册"、副标题"参与 4 本纪念册"完全一致,是用户资产的真实呈现。产品化后从服务端拉取用户参与的纪念册列表。
Q5:为什么封面用 emoji 而不是真实照片?原型阶段 emoji 封面(🎓 毕业 / ⛰️ 秋游)零资源、主题直观;真实产品用纪念册的封面照片(可自选/自动取第一张),布局代码把Text(b.emoji)换成Image(coverUrl)即可。
一句话总结:首页以"双行品牌头 + 创建引导 Banner + 纪念册列表"三区结构完成了集体记忆的展示与入口。"记录我们共同的青春"的副标题点明集体属性、📔 渐变 Banner 承担创建 CTA、"封面 + 数据(照片/人数)+ 查看入口"的纪念册大卡让每本册子的厚度与参与度一目了然——101 行代码,一个让用户"想翻开回忆"的纪念册首页。
十三、开发者视角:首页的调试与验证技巧
- 长标题的省略:
maxLines(2)+ Ellipsis + 明确宽度三件套——"计科2022级毕业纪念"这类长标题在卡片内两行可容,验证更长标题(如"计算机科学与技术2022级1班毕业纪念册")的省略位置与卡片高度稳定性。 - 封面图块的对齐:80×90 封面 + 40 号 emoji 垂直居中(
justifyContent(FlexAlign.Center))——emoji 在不同字体下垂直位置略有差异,真机验证"封面与右侧文字顶对齐"是否稳定。 - Banner 点击热区:整卡
onClick覆盖全宽——确认文字区、图标区都可点,无"点了没反应"的边界;同时注意 Banner 与列表的点击不冲突(不同卡片独立事件)。 - 数据自洽回归:首页 4 本纪念册与我的页"4 纪念册"、副标题"参与 4 本纪念册"——修改任意一处需同步(建议抽公共常量),系列验收标准。
- 列表性能:纪念册数量有限(一个班级几本),
ForEach足够;若未来支持"纪念册广场"(全校/全网),需LazyForEach+ 分页加载,首页结构不变。
十四、FAQ 与一句话总结
Q6:首页为什么不显示纪念册封面图片?原型用 emoji 封面(🎓/⛰️)零资源、主题直观;真实产品可让创建者上传封面照(或自动取第一张照片),把Text(b.emoji)换成Image(coverUrl)即可,布局零改动。
Q7:4 本纪念册是怎么来的?静态数组模拟"用户参与的纪念册"——毕业(计科2022级)、班级(软件工程)、社团、秋游四类覆盖校园集体生活的主要场景;产品化后从服务端拉取"我参与的纪念册"列表(含成员身份)。
Q8:"全部 >"入口能点吗?Demo 未挂事件。产品化后跳转"全部纪念册"页(含他人分享的/广场上的纪念册),首页"我的纪念册"与"全部"两级目录。
Q9:创建纪念册需要什么条件?产品化后需登录(班级身份)、填册名、选主题——创建后邀请同学加入(成员数从 1 开始增长),与首页"👥 成员数"字段衔接。
Q10:纪念册会被删除吗?纪念册是"永久记忆"的承诺——产品应禁止普通成员删除、管理员删除需二次确认且可导出备份;这与留言页"永久保存"、我的页"校友沉淀"的定位一致。这些 FAQ 与前面的拆解共同构成本页的完整解析。
最后从验收视角确认:四张实机截图覆盖了首屏(品牌头+创建 Banner+第一本纪念册)、Banner 点击(创建纪念册 Toast)、纪念册点击(计科2022级毕业纪念 Toast)、滚动底部(四本纪念册全览)四个状态,渐变 Banner、封面图块、数据行、查看入口、整卡点击均验证正常。跨页数据自洽通过核对——首页 4 本纪念册与我的页"4 纪念册"、副标题"参与 4 本纪念册"完全一致,相册页"班级相册"对应首页"计科2022级毕业纪念"(🎓 毕业相册),留言页"毕业寄语"对应 Banner"邀请同学添加留言"。整页 101 行代码完成"集体记忆展示 + 创建引导"的完整结构,验收通过,可作为纪念册/集体记忆类产品首页的参考范本。
再补充一处细节:Banner 的渐变(#A29BFE → #C4BEF5)与我的页 UserCard 完全同款——品牌渐变在"创建入口"与"个人中心"两处复用,用户对"纪念册的淡紫"形成条件反射式的品牌记忆。而封面图块的 80×90 尺寸(宽 80 高 90)比正方形略高,是有意的"书本比例"(纪念册是竖开的书),这种"图块比例呼应产品形态"的细节,正是让纪念册首页区别于普通列表页的质感所在。至此,从品牌色到图块比例,首页的每一处设计都在悄悄讲述"这是一本关于青春的书",整页 101 行代码的完成度也因此远超其体量。