【观止·诗史汇 HarmonyOS 实战系列 01】从 0 到 1:诗文与历史学习 App 的单机架构

系列背景:这个系列记录《观止·诗史汇》这个本地优先的诗文与历史学习 App,从工程骨架、内容包、页面组织、练习、收藏笔记到统计设置的完整实现。第 01 篇聚焦“从 0 到 1:诗文与历史学习 App 的单机架构”,继续沿着真实工程问题拆解 HarmonyOS NEXT / ArkTS / ArkUI 的落地方式。

很多古诗文 App 容易停留在“列表 + 详情”的层面,内容能看,但学习链路断裂。《观止·诗史汇》的第一版目标,是先把诗文、历史、地理、练习、收藏、统计这些入口组织成一个离线可运行的 HarmonyOS 应用。

源码对象总览

文件 职责
entry/src/main/ets/pages/Index.ets 5 个底部 Tab 容器和产品入口
features/Index.ets 业务页面与服务的统一导出
commons/Index.ets 主题、路由、工具和通用 UI 的公共出口
doc/应用介绍.md 产品定位与使用场景

一、真实工程问题:不是做诗词列表,而是做学习闭环

很多古诗文应用的第一版会从“诗词列表 + 详情页”开始,这当然能跑,但很快会遇到一个问题:用户读完一首诗以后,下一步是什么?如果没有历史脉络,他不知道这首诗为什么在那个时代出现;如果没有地理关联,长安、洛阳、汴梁、黄州只是字面地名;如果没有练习和错题,背诵与复盘不能沉淀;如果没有收藏和笔记,用户自己的学习痕迹也留不下来。《观止·诗史汇》的主线因此不是“把诗词展示出来”,而是把阅读、理解、练习、记录和统计连成一个闭环。首页、时间轴、收藏、统计、设置构成了主框架。首页负责进入诗文、兴替、地理、练习、文脉;时间轴承接历史脉络;收藏笔记沉淀个人资料;统计页把阅读与练习行为转成反馈。这个结构让用户不是“看完即走”,而是能形成学习、练习、记录、复盘的长期路径。

二、产品结构:首屏先给用户一条清晰路线

从产品层看,首页并不只是菜单。它把“每日诗句”和“每日史事”放在顶部,用一个轻量的每日机制告诉用户今天可以读什么;再把诗文时空、兴替明鉴、古今地理、文试默写、文脉纵览五个入口放成学习地图。底部 Tab 只保留五项:首页、时间轴、收藏、统计、设置。这个取舍很克制,因为不是所有功能都适合进入一级 Tab。诗文、地理、练习、文脉更像从首页进入的学习任务;收藏、统计、设置则是跨任务的长期能力。这样做的好处是首屏不会变成“十几个按钮的功能超市”,用户打开应用时能先看到主题、每日内容和下一步。

三、首页截图:用户第一眼看到的是学习路径

下面这张图来自本机 DevEco 模拟器运行的真实应用。首页并没有堆满入口,而是先给出每日诗句和五个高频学习入口,让“诗”和“史”在首屏就建立关系。截图里可以看到,视觉上使用卷轴、山水和浅色纸感,但工程上并不是静态海报:每日诗句来自内容包,入口卡通过 routeUrl 跳转,底部 Tab 由 entry 层统一控制。

应用截图

四、工程骨架:entry、features、commons 先分清职责

工程采用 entry / features / commons 三层组织。entry 是产品入口,主要负责 EntryAbility、首页 Tab 容器和路由页面声明;features 承载业务页面、领域模型、服务和状态仓;commons 提供主题 token、路由封装、Preferences 包装、通用 UI 和工具函数。这个分层不是为了显得“架构很大”,而是为后续扩展留边界。比如首页要使用颜色、字号和卡片圆角时,只从 commons 的 AppColors、AppText、AppDimens 读取;诗文详情要跳转笔记页时,通过 Navigator 和 AppRoutes,而不是手写散落字符串;统计页要读收藏、笔记和错题数量时,通过状态仓暴露的接口,而不是直接扫页面状态。

五、入口层设计:Index 只管 Tab,不碰业务细节

entry/src/main/ets/pages/Index.ets 是整个应用的入口页面。它维护 currentKey,并把 HomePage、TimelinePage、FavoritePage、StatsPage、SettingPage 放进 Tabs。这个文件很关键,但它故意保持克制:不读取诗文内容包,不创建练习题,不直接写收藏,也不计算统计指标。它只负责产品层容器和不同 Tab 的可见性。这样的好处是,当后续要做平板侧栏、大屏垂直 Tab、或者不同设备入口差异时,改的是 entry 层布局,不会牵动诗文、地理、练习这些业务模块。

六、内容层设计:本地优先比联网 CMS 更适合第一版

当前项目没有引入服务端账号、在线 CMS 或云同步,而是把诗文内容包、历史内容包、地名数据和练习生成逻辑放在本地。这个选择很适合第一版:文史内容相对稳定,用户也需要离线阅读;本地内容包可以保证无网络时仍能打开诗文详情、历史事件和练习题。项目里的 doc/cn3e 是原始诗文 Markdown,scripts/build_poem_pack.js 会把它整理成 rawfile/poempack 下的 manifest、分类索引和详情分片,运行时由 PoemPackRepo 按需读取。历史数据同样通过 HistoryPack、HistoryEvents、HistoryAnalysis 等服务进入页面。

七、状态层设计:用户行为用 Preferences 先跑通

学习闭环必须有用户状态。项目用 AppStores.ets 收束 FavoriteStore、NoteStore、StatsStore、SettingsStore、WrongStore。收藏、文件夹、笔记、统计、设置、错题分别持久化到 Preferences 文件中,启动时通过 AppBootstrap.hydrateAll 统一恢复。这里有一个细节:状态仓默认值必须可读,hydrate 异步完成后再通知页面刷新。这样首屏不会因为等 Preferences 阻塞,也不会因为本地数据缺失直接崩掉。对于单机学习应用来说,这比一开始就引入复杂数据库更轻,也更容易调试。

八、路由层设计:统一参数比散落字符串更重要

项目的子页面跳转集中在 commons/src/main/ets/router。AppRoutes 定义页面路径,NavigateParams 定义可传参数,例如 poemId、poemShard、eventId、dynastyId、geoId、folderId、noteId。Navigator.push 对 router.pushUrl 做封装,失败时只打日志,不让调用页面崩掉。这个设计的价值会随着页面数量增加而变明显:诗文详情、历史事件详情、地理详情、收藏文件夹、笔记详情都需要跨页面传参,如果每个地方都手写字符串,后期改页面路径或参数名会非常痛苦。

九、工程取舍:先单机稳定,再扩展数据源

当前项目没有引入账号、后端 CMS 或网络同步,而是先把内容包、Preferences、本地状态和页面跳转跑通。对于文史学习类 App,这个顺序更稳:先保证离线可读、可练、可收藏,再考虑服务端能力。等本地模型稳定后,再接云同步、用户账号或在线内容审核,风险会低很多。反过来,如果一开始就把所有东西压到服务端,页面、模型和状态还没稳定,就会在接口字段、缓存、弱网和账号流程里消耗大量时间。

十、从第一版看后续扩展路线

第一版骨架跑通以后,后面的文章会沿着这条路线继续拆:第 02 篇讲三层架构边界,第 03 篇讲首页,第 04 篇讲诗文内容包,第 05 篇讲诗文详情,第 06 篇讲时间轴与事件,第 07 篇讲兴替明鉴,第 08 篇讲古今地理,第 09 篇讲文脉纵览,第 10 篇讲练习题生成,第 11 篇讲收藏笔记和错题,第 12 篇讲统计与设置。它们不是互相孤立的功能点,而是围绕同一个本地学习闭环逐层展开。

关键代码片段

@Entry
@Component
struct Index {
  @State currentKey: string = AppRoutes.TAB_HOME;
  private tabs: TabDef[] = [
    { key: AppRoutes.TAB_HOME, label: '首页' },
    { key: AppRoutes.TAB_TIMELINE, label: '时间轴' },
    { key: AppRoutes.TAB_FAVORITE, label: '收藏' },
    { key: AppRoutes.TAB_STATS, label: '统计' },
    { key: AppRoutes.TAB_SETTING, label: '设置' }
  ];
}

调试命令与验证路径

本篇对应的本机验证先从工作区和模拟器状态开始,避免只凭页面观感判断:

git status --short
& "D:\Program Files\HuaWei\DevEco Studio\sdk\default\openharmony\toolchains\hdc.exe" list targets
& "D:\Program Files\HuaWei\DevEco Studio\sdk\default\openharmony\toolchains\hdc.exe" shell aa start -a EntryAbility -b com.example.app_project02
& "D:\Program Files\HuaWei\DevEco Studio\sdk\default\openharmony\toolchains\hdc.exe" shell snapshot_display -i 0 -f /data/local/tmp/app.png -w 1080 -h 2400 -t png

如果要进一步做构建验证,可以在项目根目录执行 Hvigor 构建;如果只是分析既有实现,优先用源码定位、模拟器截图和页面链路验证。

问题复盘

这一部分最重要的经验是:不要把页面截图、数据模型和用户行为割裂开看。HarmonyOS 应用的工程质量,往往取决于模型 ID、路由参数、状态仓和页面生命周期是否一致。只要这些边界稳定,后续视觉优化、内容扩容和多端适配都会轻很多。

验收清单

  • 应用启动后默认进入首页。
  • 底部 5 个 Tab 可以在首页、时间轴、收藏、统计、设置之间切换。
  • 首页五个功能入口能跳转到对应子页面。
  • entry 不直接持有诗文、练习、收藏等业务数据。
  • features 通过统一出口暴露业务页面和状态仓。
  • commons 不反向依赖 entry 或 features。
  • 模拟器截图来自真实运行中的 com.example.app_project02。
  • 文章正文包含真实源码路径、代码片段、调试命令和验收清单。

小结

第 01 篇的核心不是展示“写了一个页面”,而是把一个真实学习 App 的工程边界讲清楚。下一篇会继续沿着项目主线,拆解相邻模块如何协作,以及这些能力如何服务于长期学习体验。

[#HarmonyOS](https://so.csdn.net/so/search/s.do?q=HarmonyOS&t=all&o=vip&s=&l=&f=&viparticle=&from_tracking_code=tag_word&from_code=app_blog_art) [#ArkTS](https://so.csdn.net/so/search/s.do?q=ArkTS&t=all&o=vip&s=&l=&f=&viparticle=&from_tracking_code=tag_word&from_code=app_blog_art) [#ArkUI](https://so.csdn.net/so/search/s.do?q=ArkUI&t=all&o=vip&s=&l=&f=&viparticle=&from_tracking_code=tag_word&from_code=app_blog_art) [#DevEco Studio](https://so.csdn.net/so/search/s.do?q=DevEco+Studio&t=all&o=vip&s=&l=&f=&viparticle=&from_tracking_code=tag_word&from_code=app_blog_art) [#鸿蒙开发](https://so.csdn.net/so/search/s.do?q=%E9%B8%BF%E8%92%99%E5%BC%80%E5%8F%91&t=all&o=vip&s=&l=&f=&viparticle=&from_tracking_code=tag_word&from_code=app_blog_art)

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐