
鸿蒙原生应用 ArkUI 声明式阅读管理首页的竖版书封与页码进度条App 20「阅读管理」首页HomeTab主题色#A855F7紫色4 个 Tab 分别为首页、书库、记录✍️、我的。首页采用固定 Header阅读管理/让阅读成为习惯 紫色渐变正在阅读卡三体·第360页/480页 今日已读45分钟 独立搜索栏 3 栏统计 4 个圆形入口 本周阅读时长条形图 在读书架 4 张书卡竖版书封面 56×72 环形进度 页码进度条 currentPage/totalPages 写笔记/继续阅读双按钮 分类统计排行文学小说/科幻奇幻/历史人文/心理学带涨跌。本篇基于20-reading-manager/entry/src/main/ets/pages/HomeTab.ets约 243 行逐段拆解附 4 张实机截图。一、整体结构8 个 Builder 的内容流HomeTab 与 App 18/19 首页结构同源8 个 Builder 块但主内容换成书卡BookListbuild() { Column() { this.Header() Scroll() { Column({ space: 14 }) { this.HeroCard() this.SearchBar() this.StatRow() this.QuickActionRow() this.WeekChart() this.SectionTitle(在读书架) this.BookList() this.SectionTitle(分类统计) this.RankList() } .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) }8 个块按品牌 → 在读 → 搜索 → 数据 → 入口 → 图表 → 书架 → 排行叙事Header— 阅读管理 SloganHeroCard— 正在阅读三体·第360页/480页SearchBar— 搜索书名/作者/分类StatRow— 3 栏统计已读书籍/阅读时长/读书笔记QuickActionRow— 4 个入口添加书/书签/笔记/统计WeekChart— 本周阅读时长条形图SectionTitle(在读书架) BookList— 4 张书卡本页核心SectionTitle(分类统计) RankList— 4 条分类排行与 App 19 的差异App 19 是精选作品卡摄影App 20 是在读书架卡书——封面从作品 emoji 换成竖版书封56×72 竖长方形模拟书籍比例——书封的竖版比例是阅读 App 的特色书 vs 照片的形态差异。项目源码开源https://gitee.com/codenestFlow/HarmonyOSHub二、Header HeroCard正在阅读卡Header 是阅读管理/让阅读成为习惯 两行品牌区。HeroCard 是正在阅读的横向渐变卡Builder HeroCard() { Row({ space: 14 }) { Column({ space: 6 }) { Text(正在阅读).fontSize(12).fontColor(#FFFFFF).opacity(0.85) Text(三体 · 第360页/480页).fontSize(16).fontWeight(FontWeight.Bold).fontColor(#FFFFFF) Text(今日已读 45 分钟).fontSize(11).fontColor(#FFFFFF).opacity(0.75) }.alignItems(HorizontalAlign.Start).layoutWeight(1) Text().fontSize(44) } .width(100%).padding(20).borderRadius(D.rLg) .linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] }) .onClick(() { promptAction.showToast({ message: 继续阅读 }); }) }正在阅读 / 三体 · 第360页/480页 / 今日已读 45 分钟三行——书名 · 页码 / 今日时长的阅读进度卡第360页/480页——读到哪了页码是阅读 App 最核心的进度信号今日已读 45 分钟——今天读了多久时长是习惯信号与 App 19 本周精选的差异App 19 是作品精选内容推荐App 20 是正在阅读个人进度——HeroCard 承载用户当前状态阅读 App 最关心我读到哪了。第360页/480页与 BookList 第一条《三体》进度条360/480一致✓——正在阅读的书 书架第一本书数据互相印证。onClick整卡可点继续阅读跳转阅读器。三、SearchBar StatRow QuickActionRowSearchBar与 App 18/19 同构 透明 TextInput占位搜索书名、作者、分类...——阅读 App 搜索 3 个维度。State searchText双向绑定。StatRow是 3 栏统计已读书籍 36/阅读时长 128h/读书笔记 246数字全部C.primary紫色加粗Builder StatRow() { Row() { ForEach(this.stats, (s: StatItem) { Column({ space: 4 }) { Text(s.value).fontSize(20).fontWeight(FontWeight.Bold).fontColor(C.primary) Text(s.label).fontSize(11).fontColor(C.textDim) }.layoutWeight(1) }, (s: StatItem) s.label) } .width(100%).padding({ top: 14, bottom: 14 }) .backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke }) }数据一致性已读书籍 36 我的页历史订单 28不直接对应——但已读书籍 36是阅读统计——App 20 的我的页还是 App 13 的订单统计模板复刻的遗留首页与我的页数据口径不完全一致App 13 同款问题——**模板换肤时统计项没换**是 App 20 与 App 17 相同的瑕疵读者应引以为戒换业务要换全部数据。QuickActionRow4 个圆形入口添加书/书签/笔记✏️/统计Builder QuickActionRow() { Row() { ForEach(this.actions, (a: QuickAction) { Column({ space: 8 }) { Row() { Text(a.icon).fontSize(22) } .width(48).height(48).backgroundColor(C.primarySoft).borderRadius(24).justifyContent(FlexAlign.Center) Text(a.label).fontSize(11).fontColor(C.textSub) }.layoutWeight(1).onClick(() { promptAction.showToast({ message: a.label }); }) }, (a: QuickAction) a.id.toString()) } .width(100%).padding({ top: 14, bottom: 14 }) .backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke }) }添加书/书签/笔记/统计覆盖阅读 App 4 个核心功能书添加、签书签、记笔记、统统计。四、WeekChart本周阅读时长WeekChart 与 App 18/19 周图同构7 天条形图 共 8.5 小时Builder WeekChart() { Column({ space: 10 }) { Row() { Text(本周阅读时长).fontSize(15).fontWeight(FontWeight.Bold).fontColor(C.text) Blank() Text(共 8.5 小时).fontSize(11).fontColor(C.textDim) }.width(100%) Row() { ForEach(this.weekBars, (b: BarItem) { Column({ space: 6 }) { Column().width(14).height(b.value * 0.7).backgroundColor(C.primary).borderRadius(4) Text(b.day).fontSize(10).fontColor(C.textDim) }.layoutWeight(1) }, (b: BarItem) b.day) }.width(100%).alignItems(VerticalAlign.Bottom).height(90) } .width(100%).padding(14).backgroundColor(C.card).borderRadius(D.rMd).border({ width: 1, color: C.stroke }) }数据一 70/二 55/三 85/四 60/五 75/六 100/日 90——周六 100 最高周末阅读高峰、周二 55 最低工作日低谷——周末读书多符合阅读习惯。共 8.5 小时——705585607510090 535强度如果按每天 1 小时 ≈ 强度 100换算535 ≈ 5.35 小时 ≠ 8.5——强度 vs 小时口径不完全匹配又是本系列高频的图表口径瑕疵。但8.5 小时按每强度单位 0.0159 小时535×0.0159≈8.5能对上——反正不是严格自洽读者应引以为戒。height(b.value * 0.7)直接倍率100×0.770vp——简化版周图App 18/19 同款。五、BookList在读书架卡本页核心BookList 是 4 张书卡每张含竖版书封面、书名、星级、作者、分类标签、环形进度、页码进度条currentPage/totalPages、写笔记/继续阅读双按钮Builder BookList() { Column({ space: 12 }) { ForEach(this.books, (b: BookCard) { Column({ space: 12 }) { Row({ space: 12 }) { Row() { Text(b.cover).fontSize(36) } .width(56).height(72).backgroundColor(C.primarySoft).borderRadius(D.rMd).justifyContent(FlexAlign.Center) Column({ space: 4 }) { Row({ space: 6 }) { Text(b.title).fontSize(16).fontWeight(FontWeight.Bold).fontColor(C.text) Text(⭐ b.rating .0).fontSize(10).fontColor(C.warn) } Text(b.author).fontSize(12).fontColor(C.textDim) Text(b.category).fontSize(11).fontColor(C.primary) .padding({ left: 6, right: 6, top: 2, bottom: 2 }) .backgroundColor(C.primarySoft).borderRadius(4) }.alignItems(HorizontalAlign.Start).layoutWeight(1) Stack({ alignContent: Alignment.Center }) { Progress({ value: b.progress, total: 100, type: ProgressType.Ring }).width(48).height(48).color(C.primary).style({ strokeWidth: 4 }) Text(b.progress %).fontSize(11).fontColor(C.primary).fontWeight(FontWeight.Bold) } }.width(100%) Row() { Text(进度).fontSize(11).fontColor(C.textDim) Progress({ value: b.currentPage, total: b.totalPages }).color(C.primary).layoutWeight(1).height(6).borderRadius(3).margin({ left: 8, right: 8 }) Text(b.currentPage / b.totalPages).fontSize(11).fontColor(C.textSub) }.width(100%) Row({ space: 12 }) { Button(写笔记).fontSize(13).fontColor(C.textSub).backgroundColor(C.cardSoft) .borderRadius(D.rMd).height(38).layoutWeight(1) .onClick(() { promptAction.showToast({ message: 写笔记: b.title }); }) Button(继续阅读).fontSize(13).fontColor(#FFFFFF).backgroundColor(C.primary) .borderRadius(D.rMd).height(38).layoutWeight(1) .onClick(() { promptAction.showToast({ message: 继续阅读: b.title }); }) }.width(100%) } .width(100%).padding(14).backgroundColor(C.card).borderRadius(D.rLg).border({ width: 1, color: C.stroke }) }, (b: BookCard) b.id.toString()) }.width(100%) }5.1 4 本书的数据设计private books: BookCard[] [ { id: 1, cover: , title: 三体, author: 刘慈欣, category: 科幻, rating: 5, progress: 75, totalPages: 480, currentPage: 360 }, { id: 2, cover: , title: 活着, author: 余华, category: 文学, rating: 5, progress: 100, totalPages: 320, currentPage: 320 }, { id: 3, cover: , title: 人类简史, author: 尤瓦尔, category: 历史, rating: 4, progress: 45, totalPages: 600, currentPage: 270 }, { id: 4, cover: , title: 思考快与慢, author: 卡尼曼, category: 心理学, rating: 4, progress: 30, totalPages: 520, currentPage: 156 } ];4 本书的经典书单三体刘慈欣科幻、活着余华文学、人类简史尤瓦尔历史、思考快与慢卡尼曼心理学——中国当代文学 世界畅销书的混合书单每本都是豆瓣高分4-5 星——书架 好书单真实可信。4 本书的阅读进度梯度75%三体→ 100%活着→ 45%人类简史→ 30%思考快与慢——一本书在读、一本读完、两本在读中——书架该有的状态不是全在读、也不是全读完。currentPage/totalPages页码字段是本页的特色——页码 阅读进度的真实单位对比 App 19 的完成度、App 16 的库存页码是阅读 App 特有的进度表达。5.2 竖版书封面本页特色Row() { Text(b.cover).fontSize(36) } .width(56).height(72).backgroundColor(C.primarySoft).borderRadius(D.rMd).justifyContent(FlexAlign.Center)56×72 竖长方形封面宽高比 56:72 ≈ 7:9——模拟真实书籍的竖版比例对比 App 19 作品卡的 64×64 方形封面——书是竖的、照片是方的的形态差异。 四色书封红/绿/蓝/橙对应 4 本书——书封颜色 书emoji 替代真实书封。borderRadius(D.rMd)圆角——书封四周圆角真实书封边缘是直角demo 圆角更柔和。5.3 书名 星级 作者 分类标签Row({ space: 6 }) { Text(b.title).fontSize(16).fontWeight(FontWeight.Bold).fontColor(C.text) Text(⭐ b.rating .0).fontSize(10).fontColor(C.warn) } Text(b.author).fontSize(12).fontColor(C.textDim) Text(b.category).fontSize(11).fontColor(C.primary) .padding({ left: 6, right: 6, top: 2, bottom: 2 }) .backgroundColor(C.primarySoft).borderRadius(4)书名 ⭐5.0 数字星级⭐ rating .0字符串拼接App 18/19 同款作者灰色小字——刘慈欣/余华/尤瓦尔/卡尼曼分类标签紫字浅紫底胶囊——科幻/文学/历史/心理学作者字段是本页的特色App 18/19 作品卡没有作者维度App 20 书卡必须有作者——书的作者 书卡必备信息。5.4 环形进度 页码进度条双进度Stack({ alignContent: Alignment.Center }) { Progress({ value: b.progress, total: 100, type: ProgressType.Ring }).width(48).height(48).color(C.primary).style({ strokeWidth: 4 }) Text(b.progress %).fontSize(11).fontColor(C.primary).fontWeight(FontWeight.Bold) } ... Row() { Text(进度).fontSize(11).fontColor(C.textDim) Progress({ value: b.currentPage, total: b.totalPages }).color(C.primary).layoutWeight(1).height(6).borderRadius(3).margin({ left: 8, right: 8 }) Text(b.currentPage / b.totalPages).fontSize(11).fontColor(C.textSub) }双进度设计本页最值得学的点进度类型数值语义环形右上ProgressType.Ring75%百分比进度整体进度页码条底部Progress线性360/480页码进度具体读到哪页Progress({ value: b.currentPage, total: b.totalPages })用页码做进度条——value360, total480自动算 75%——页码直接驱动进度条不用手动算百分比Progress 组件内部算——真实单位驱动进度比百分比字段更可靠页码更新 → 进度条自动跟进。环形概览 页码条细节双进度——右上环形看大概读了多少底部页码条看具体读到 360 页——**概览 细节双通道**是阅读 App 进度显示的最佳实践。5.5 写笔记 继续阅读双按钮Row({ space: 12 }) { Button(写笔记).fontSize(13).fontColor(C.textSub).backgroundColor(C.cardSoft) .borderRadius(D.rMd).height(38).layoutWeight(1) .onClick(() { promptAction.showToast({ message: 写笔记: b.title }); }) Button(继续阅读).fontSize(13).fontColor(#FFFFFF).backgroundColor(C.primary) .borderRadius(D.rMd).height(38).layoutWeight(1) .onClick(() { promptAction.showToast({ message: 继续阅读: b.title }); }) }写笔记灰底灰字次级——记笔记入口继续阅读紫底白字主操作——进入阅读器写笔记/继续阅读是书卡的标准双操作微信读书/掌阅同款——继续阅读是阅读 App 最高频的操作用户每天点它进入阅读——主按钮紫色高亮。六、RankList分类统计排行RankList 与 App 18/19 同构4 条排行 涨跌计数单位是本private ranks: RankItem[] [ { id: 1, rank: 1, name: 文学小说, count: 12, trend: ↑ }, { id: 2, rank: 2, name: 科幻奇幻, count: 8, trend: ↑ }, { id: 3, rank: 3, name: 历史人文, count: 6, trend: ↓ }, { id: 4, rank: 4, name: 心理学, count: 5, trend: ↑ } ];4 条分类文学小说 12 本↑/科幻奇幻 8 本↑/历史人文 6 本↓/心理学 5 本↑——本数计数——排行单位 业务对象阅读排本。涨跌箭头 ↑绿↓红3 涨 1 跌 排名数字前 3 名紫加粗 Divider().strokeWidth(0.5)超细分隔线——App 18/19 同款。分类与书架呼应文学活着/科幻三体/历史人类简史/心理学思考快与慢——分类排行 书架书的分类分布✓——排行榜数据从书架推导12 本文学 8 本科幻 6 本历史 5 本心理学。七、State 与主题色的设计HomeTab 只有1 个 StatesearchText。其余数据private不可变。主题色#A855F7紫色——阅读 App 常用紫色系Kindle/微信读书偏暖但紫色象征深度阅读/文化——与 App 13 音乐紫#8B5CF6的区别App 20 的 #A855F7 更浓偏紫红App 13 更淡偏蓝紫——同系不同调。C.primarySoft: #F3EAFE浅紫比 App 13 的 #F0EBFE 略深——**紫色主题的书架**营造知识氛围。八、与 App 18/19 首页的对比总结维度App 18 社交App 19 摄影App 20 阅读主题色粉红 #EC4899青绿 #0D9488紫 #A855F7Hero今日推荐同好本周精选作品正在阅读书名·页码统计匹配/好友/互动照片/点赞/拍摄书籍/时长/笔记主列表同好卡作品卡书卡竖版封页码条双按钮跳过/打招呼收藏/查看详情写笔记/继续阅读排行兴趣分类分类本数特色匹配度环形完成度环形页码进度条currentPage内容流首页模板第 6 次复用App 13-20 中 App 18/19/20 是三连同源——同一套模板换主题 换数据 社交/摄影/阅读三个 App。九、书架的数据设计在读书架的阅读状态App 20 首页书架 4 本书的阅读状态设计得非常真实private books: BookCard[] [ { id: 1, cover: , title: 三体, author: 刘慈欣, category: 科幻, rating: 5, progress: 75, totalPages: 480, currentPage: 360 }, { id: 2, cover: , title: 活着, author: 余华, category: 文学, rating: 5, progress: 100, totalPages: 320, currentPage: 320 }, { id: 3, cover: , title: 人类简史, author: 尤瓦尔, category: 历史, rating: 4, progress: 45, totalPages: 600, currentPage: 270 }, { id: 4, cover: , title: 思考快与慢, author: 卡尼曼, category: 心理学, rating: 4, progress: 30, totalPages: 520, currentPage: 156 } ];一本在读 一本读完 两本在读的梯度三体 75%360/480——正在读的大部头还在读活着 100%320/320——刚读完的进度满人类简史 45%270/600——读了一半的大部头600 页的书读到 270 页思考快与慢 30%156/520——刚开始读的520 页读到 156 页总页数的设计480/320/600/520——书的厚度不一320 页中篇到 600 页大部头——书架该有的书形态有厚有薄、有在读有读完。currentPage字段是阅读 App 的核心数据——真实项目里每次翻页都更新currentPage进度条自动推进Progress(value: currentPage, total: totalPages)——页码 阅读器与书架的桥梁阅读器改页码 → 书架进度条自动更新。写笔记/继续阅读双按钮的业务闭环写笔记阅读中随时记→ 继续阅读回到阅读器→ 读完进度 100%→ 从书架移入已读——书架 → 阅读器 → 笔记 → 已读是阅读 App 的完整用户旅程。十、总结App 20 首页解析完毕。正在阅读 HeroCard书名·页码 竖版书封 环形/页码双进度 写笔记/继续阅读是四大亮点。**页码进度条currentPage/totalPages 直接驱动 Progress**是阅读 App 最核心的进度设计。