HarmonyOS 6 鸿蒙APP应用实战:基于 ArkUI V2 打造儿童古诗学习宝 App 从 0 到 1
《古诗学习宝》是一款专为小学生设计的鸿蒙原生应用,收录了1-6年级277首必背古诗。该应用提供4种背诵模式(默写填空/选择题/连线题/听音造句)、自动错题本功能和游戏化激励体系,采用宣纸色系古典美学设计,无广告和内购。技术架构基于HarmonyOS 6 + ArkUI V2,包含视图层、服务层和数据持久化层,使用本地JSON数据库和Preferences存储。目前已上架华为应用市场,为家长和孩子提
1、前言
🎉 新作已上架 —— 「古诗学习宝」鸿蒙原生应用已在华为应用市场上架,欢迎各位家长 / 老师 / 鸿蒙开发者下载体验!搜索「古诗学习宝」即可,零广告、零内购、纯净版。觉得好用,烦请帮忙点个五星 🌟,您的反馈是我继续打磨的最大动力。
陪娃背古诗这件事,每个家长都不陌生 —— 一年级《静夜思》、三年级《登鹳雀楼》、五年级《将进酒》,12 册语文课本里前前后后 277 首必背古诗,错一句还得重背。
市面上的古诗 App 我下载过十几款,真正给小学生用的不多:要么开屏广告糊脸、要么诱导内购、要么把"背诵"做成了小学奥数式的填鸭题、要么 UI 花花绿绿完全没有古诗词该有的文化氛围。
作为一个鸿蒙开发者 + 一个一年级小朋友的家长,我用一个月业余时间从 0 写了这款**「古诗学习宝」**,专门给小学生设计:
- 📚 277 首小学必背古诗全收录 —— 1~6 年级 上下册同步课本、12 个朝代分组、4 大诗人主题(李白 / 杜甫 / 王维 / 苏轼)
- 🎯 4 种背诵模式 —— 默写填空 / 选择题 / 连线题 / 听音造句,挑娃喜欢的练
- 📝 错题本自动派生 —— 背错的题自动记录、复习时优先弹出、可"标记已掌握"软删除
- ⭐ 游戏化激励体系 —— 打卡 / 连续天数 / 5 段等级(童生→秀才→举人→进士→诗仙)/ 8 大成就奖章
- 🎨 宣纸色系古典美学 —— 不是花花绿绿,是真正配得上诗词氛围的视觉:宣纸色 + 墨绿 + 朱砂 + serif 字体 + 国画素材
- 🔒 零广告 / 零内购 / 零追踪 —— 全本地存储 Preferences,不联网、不收集任何数据
技术栈基于 HarmonyOS 6 + ArkUI V2 原生实现,使用 @kit.ArkUI / @kit.ArkData / @kit.MediaLibraryKit 等系统 Kit 完成路由、持久化、相册接入。本文是「古诗学习宝」开发的总览复盘:产品定位、技术选型、架构设计、12 张实拍截图配解读、6 大技术亮点速览、上架真实经验,让你30 分钟看懂一款完整鸿蒙应用从 0 到 1 的全貌。
👉 后续会按主题拆 5 篇文章(凹槽 TabBar / Navigation 跨页同步 / 7 类弹窗选型 / 错题本派生系统 / 等级成就算法),每篇代码即贴即用。
2、整体架构
2.1 技术架构图
┌──────────────────────────────────────────────────────────────────┐
│ View 视图层 │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Index.ets (Navigation 根) + MainTabsPage.ets (5 大 Tab) │ │
│ │ ┌─ HomeView 首页 ─┬─ CategoryPage 分类 ─┬─ PlanView 计划 │ │
│ │ ┬─ RecordView 记录 ─┬─ ProfileView 我的 │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 13 个 NavDestination 子页面: │ │
│ │ PoemList / PoemDetail / ReciteMode / 4 种背诵模式页 / │ │
│ │ CharStudy / Achievements / Feedback ... │ │
│ └──────────────────────────────────────────────────────────┘ │
└──────────────────────────────┬───────────────────────────────────┘
│ V2 状态:@Local @Param @Event @Computed
▼
┌──────────────────────────────────────────────────────────────────┐
│ Service 服务层(单例) │
│ PoemService │ RecordService │ FavoriteService │
│ PlanService │ WrongQuestionService │ PhotoHistoryService │
└──────────────────────────────┬───────────────────────────────────┘
│ 数据流
▼
┌──────────────────────────────────────────────────────────────────┐
│ 数据持久化层 + 系统 Kit │
│ @kit.ArkData (Preferences) - 10 类 StorageKey │
│ @kit.MediaLibraryKit - PhotoViewPicker / Camera Picker │
│ @kit.ArkUI - router / promptAction / window │
│ 本地诗词数据库(JSON 静态资源 + 拼音生成工具) │
└──────────────────────────────────────────────────────────────────┘
2.2 项目目录结构
wqsy/
└── entry/src/main/
├── ets/
│ ├── entryability/EntryAbility.ets # 应用入口
│ ├── common/
│ │ ├── Constants.ets # 路由名/StorageKey/TabKey
│ │ ├── Format.ets # uid / dateStr / todayStr
│ │ └── UserLevel.ets # 5 段等级算法
│ ├── model/
│ │ ├── Poem.ets # 诗词模型
│ │ ├── StudyRecord.ets # 学习记录
│ │ └── WrongQuestion.ets # 错题模型
│ ├── service/
│ │ ├── PoemService.ets # 诗词数据查询
│ │ ├── RecordService.ets # 学习记录
│ │ ├── FavoriteService.ets # 收藏
│ │ ├── PlanService.ets # 计划/打卡
│ │ ├── WrongQuestionService.ets # 错题本
│ │ └── PreferencesUtil.ets # 持久化封装
│ ├── components/
│ │ ├── BottomTabBar.ets # 凹槽 Tab 栏
│ │ ├── PoemCard / StatCard / NavBar / EmptyView ...
│ └── pages/
│ ├── Index.ets # Navigation 根
│ ├── MainTabsPage.ets # 5 Tab 容器
│ ├── views/
│ │ ├── HomeView / CategoryView /
│ │ ├── PlanView / RecordView / ProfileView
│ ├── CategoryPage / PoemListPage / PoemDetailPage
│ ├── ReciteModePage
│ ├── ReciteFillPage / ReciteChoicePage /
│ ├── ReciteConnectPage / ReciteListenPage
│ ├── CharStudyPage / AchievementsPage / FeedbackPage
└── resources/
├── base/
│ ├── element/{color,float,string}.json # 设计 token
│ ├── media/ # 27 张资源图 + 6 SVG 图标
│ └── profile/main_pages.json
└── dark/element/color.json # 暗色模式适配
2.3 架构模式说明
经典「视图 + 服务 + 数据」三层 + 系统 Kit 集成:
| 层级 | 文件示例 | 职责 |
|---|---|---|
| 视图层 | HomeView.ets / ProfileView.ets |
UI 渲染、用户交互、@Local 状态管理 |
| 服务层 | FavoriteService.ets 等 4 个单例 |
业务逻辑、跨页面状态唯一源 |
| 持久层 | PreferencesUtil.ets + 10 个 StorageKey |
JSON 序列化、跨重启数据保留 |
| 系统 Kit | @kit.ArkData / @kit.MediaLibraryKit / @kit.ArkUI |
Preferences、PhotoPicker、router、promptAction |
设计原则:3 件事在项目里贯彻到底——① 状态只通过
@Param+@Event单向传递(V2 模式)② 持久化只走 Service 单例(页面不直接操作 Preferences)③ 路由参数对象化(用interface CategoryRouteParam等强类型替代Record<string, any>)。
3、效果展示
3.1 启动页 - 水墨书卷 + 入场动画

冷启动第一眼就是浓郁的中国风:宣纸色背景 + 远山水墨纹 + 左下竹叶素材;中央**水墨书卷圆形 Logo(带山日图案)**配 12vp 阴影;下方品牌字「古诗学习宝」40vp 加粗、绿色 #436444、字距 4vp;副标题「教材同步 · 启蒙必备」两侧带装饰线,再下一行「古诗学习 · 背诵 · 赏析」点出 3 大核心能力。
底部 160vp 进度条 3 秒匀速从 0 走到 100%,配合「正在为你打开诗书 · · ·」呼吸感文案;右下「跳过」胶囊按钮让用户随时进入主页面,尊重用户时间。
动画分层设计:印章 200ms 起 600ms 弹入、标题 500ms 起 700ms 上浮淡入、副标题 900ms 起 600ms 淡入——错峰入场,3 秒看完整套节奏完全不局促。代码上用 @Local 状态 + getUIContext().animateTo 命令式动画驱动,aboutToDisappear 里清理 timer 防泄漏,是「启动页 + 动画 + 自动跳转」的标准模板。
启动页代码全部在
SplashPage.ets,第 6 篇文章会详细拆它怎么用 V2 动画 + Stack 多层合成 + 进度条 setInterval 实现。
3.2 首页 - 古典氛围 + 快捷入口

打开就是浓浓中国风:宣纸色背景 #F9F7F2 + serif 字体 + 国画素材封面。顶部「你好,小诗友 👋 今天也要快乐学习哦」+ 卡通头像(李白形象)。**「今日推荐」**卡片可左右滑切换,当前是清代王士禛的《题秋江独钓图》。
下方 8 个快捷入口:背诵 / 生字 / 今日一首 / 随机一首 / 打卡 / 收藏 / 成就 / 挑战 —— 全部走 NavPathStack.pushPathByName 跳转到对应详情页或切到对应 Tab。最下方「猜你喜欢」继续推荐诗词。
底部 Tab 栏是整个 App 视觉亮点:左 2 个(首页 / 分类)+ 中央凹槽凸起的「学习」(白色圆形带书本图标 + 阴影向上凸出)+ 右 2 个(记录 / 我的),这种设计模仿小红书 / 闲鱼底栏,第 1 篇文章会详细讲怎么用原生 ArkUI 手写凹槽凸起。
3.3 分类 - 277 首 6 年级全收录

顶部「分类」NavBar + 搜索框 + 3 个分类 Tab(按年级 active / 按主题 / 按诗人)。下方第一张是"小学生必背古诗词 277 首经典古诗词 [去学习 ›]"主推卡。
往下是 6 个年级卡,每个卡显示 共 X 首 + 已学进度 + 百分比:
- 一年级(启蒙)共 13 首 0%
- 二年级(基础)共 14 首 0%
- 三年级(提升)共 17 首 0%
- 四年级(进阶)共 39 首 3%
- 五年级(进阶)共 68 首 0%
- 六年级(拓展)共 126 首 0%
进度数字是 @Computed 实时计算,根据 RecordService 的学习记录自动派生。
3.4 学习计划 - 月历 + 今日任务

「学习计划 / 每天进步一点点 ✨」+ 顶部月历卡 2026年5月 + 3 张统计胶囊(🔥1 连续 / 📅1 本月 / 🏆1 累计)。下方是完整月历,13 号是今天(绿色圆圈高亮),已打卡的天会显示打钩。
底部「今日任务 0/3」:3 张诗词任务卡(学新诗《新雷》/ 背诵《寒菊》/ 复习《春日》),每张右侧「去学习 ›」按钮一键进入对应页面。
这就是「Keep 同款打卡 + 等级激励」的鸿蒙版实现,第 5 篇文章详细讲
@Computed派生算法。
3.5 学习记录 - 错题本 active 状态

顶部 4 张统计卡:本周打卡 1 天 / 已学诗词 1 首 / 平均分 / 连续 1 天。然后是本周打卡日历条(7 天)。
下方 3 个 sub-tab:学习记录 0 / 背诵记录 3 / 错题本 3(当前选中)。错题本里显示 2 道《夏日绝句》的选择题错题——每道题展示「我的答案 / 正确答案 / 再练这首 / 已掌握 ✓」。
这就是错题本自动派生系统,第 4 篇文章详细讲
WrongQuestionService复合 key 去重 + 软删除字段设计。
3.6 我的 - 等级进阶 + 菜单

头像区:卡通李白头像 + 名字「小诗友」+ 一年级 + 童生 + 等级进度条(再 9 首升「秀才」)。
4 张统计:连续天数 1 / 已学诗词 1 / 收藏 0 / 总天数 1。
「今日学习目标」进度条 1/3 +「已经开始啦,再坚持一下完成今日目标!」鼓励语。
下方 5 个菜单:成就奖章 ⭐ / 我的收藏 ⭐ / 每日学习目标(3 首)🎯 / 意见反馈 💬 / 关于 ℹ️。
最底是杜甫名言「读书破万卷,下笔如有神」+ 出处《奉赠韦左丞丈二十二韵》。
5 段等级(童生→秀才→举人→进士→诗仙)的算法在
UserLevel.ets,第 5 篇详细讲。
3.7 头像选择 - 自定义 Bottom Sheet 弹窗

点头像弹起底部浮层:「更换头像」+ 3 个动作(拍照 / 相册 / 清除)+ 4 个卡通预设(李白 / 杜甫 / 王维 / 苏轼水墨画头像)+ 取消按钮。
- 拍照:
new cameraPicker.Picker调起系统相机零权限 - 相册:
new photoAccessHelper.PhotoViewPicker.select()零权限选图 - 卡通:直接存
cartoon:libai等协议字符串到AppStorage
零权限三合一头像是 wqsy 的一个特色实现,第 3 篇弹窗大全会顺带提到这种 Bottom Sheet 形态。
3.8 学习目标 picker - showActionMenu

点「每日学习目标」菜单项 → 弹出 showActionMenu 系统级 picker:
- 1 首 / 天(轻松)
- 2 首 / 天
- 3 首 / 天(推荐) 绿色高亮
- 4 首 / 天
- 5 首 / 天(挑战) 红色警示
- 取消
不同 button 用不同 color 字段表达"推荐 vs 挑战"的产品意图——这是 ArkUI 七大类弹窗之一。
第 3 篇弹窗大全会展开 ActionMenu / Dialog / ActionSheet / TextPickerDialog 等 7 类弹窗在真实场景里的选型决策。
3.9 诗词详情 - 注释 / 译文 / 赏析 / 作者

顶部 NavBar 返回 + 标题「夏日绝句」。中央竖排诗题 + 作者「宋·李清照」+ 4 行诗句:
生当作人杰,
死亦为鬼雄。
至今思项羽,
不肯过江东。
下方 4 个内容 Tab:注释 active / 译文 / 赏析 / 作者。当前显示「人杰 — 人中豪杰。」
底部 3 个动作按钮:收藏(次按钮)/ 开始背诵(主按钮深绿色)/ 生字(次按钮)。
这是单首诗的"中枢页面",从这里能跳转去4 种背诵模式,第 4 篇文章讲它们与错题本的派生关系。
3.10 选择背诵方式 - 4 种模式入口

「选择背诵方式」标题。诗题「夏日绝句」+ 元数据胶囊:4年级·上册 / 难度 ⭐⭐⭐⭐☆ / 爱国。
4 个模式卡 2×2 网格:
- 默写填空(推荐)✏️ - 挖空补字,巩固记忆
- 选择题 A - 辨认上下句
- 连线题 🔗 - 上下句配对,强化记忆
- 听音造句 🎧 - 听音排字,还原诗句
下方"诗文预览"+“学习贴士:建议顺序:先用「默写填空」打牢字词基础,再用「选择题」检验上下句记忆。”
3.11 选择题答题中

「选择题」标题 + 第 1/3 题进度。
上句:生当作人杰,
请选择下一句:
Ⓐ 死亦为鬼雄。 ✓ 正确
Ⓑ 不是遮头是使风。
Ⓒ 野火烧不尽,
Ⓓ 出没风波里。
如果用户选错(B/C/D),结果会通过 WrongQuestionService.add 自动派生一条错题到错题本,记录字段:poemId / mode=‘choice’ / prompt=‘上句:生当作人杰,’ / userAnswer / correctAnswer。同一首诗 + 同模式 + 同 prompt 的错题去重合并。
3.12 成就奖章 - 8 大徽章按分类展示

顶部「成就奖章」NavBar + 大徽章墙卡(🏆 我的徽章墙 0/8 + 大圆环 0% 完成 + “坚持学习,解锁第一枚徽章 ✨”)。
下方按 4 大类分组:
- 📖 学习篇 0/2:初入诗坛(学习 10 首古诗 1/10 = 10%)+ 博学多才(学习 50 首 1/50 = 2%)
- ✏️ 背诵篇 0/2:背诵达人(50 次背诵 3/50 = 6%)+ 百战不殆(100 次 3/100 = 3%)
- 🔥 坚持篇 0/3(截断显示):连续 X 天打卡 / 累计 Y 天 / …
- ⭐ 收藏篇 0/1(未显示)
每个徽章卡:图标 + 名字 + 进度条 + 当前/目标 + 百分比 角标。所有数据 @Computed 实时从 RecordService / FavoriteService 派生,不存独立状态。
第 5 篇文章详讲
@Computed派生算法 + 8 大成就的条件设计。
4、技术选型与关键决策
4.1 ArkUI V2 全面 Opt-in(@ComponentV2 + @Local + @Param + @Event)
项目启动时 HarmonyOS 6 刚发布 V2 状态管理,权衡后全面用 V2(不混用 V1)。理由:
- 差分粒度精确到字段:
@Local单字段变化只重渲对应组件,比 V1 的@State全量 diff 性能更好 @Computed派生缓存:成就进度、统计数字等派生值自动缓存@Event强类型回调:替代 V1 的非装饰器属性,IDE 自动补全更清晰
@Entry
@ComponentV2
struct Index {
@Local pathStack: NavPathStack = new NavPathStack();
@Local favVersion: number = 0; // 跨页同步版本号
@Local avatarRef: string = '';
}
@ComponentV2
struct PoemCard {
@Param poem: PoemBrief = {} as PoemBrief;
@Param favorite: boolean = false;
@Event onTap: (id: string) => void = () => {};
@Event onFav: (id: string) => void = () => {};
}
第 2 篇 Navigation 文章会展开讲
favVersion版本号是如何让"详情页改了收藏态、返回首页自动刷新"的。
4.2 单一 Navigation + 13 个 NavDestination
整个 App 只有一个 Navigation 根(在 Index.ets),所有页面都注册成 NavDestination:
@Builder
PageMap(name: string) {
if (name === RouteName.Category) {
CategoryPage({ pathStack: this.pathStack })
} else if (name === RouteName.PoemList) {
PoemListPage({ pathStack: this.pathStack })
} else if (name === RouteName.PoemDetail) {
PoemDetailPage({
pathStack: this.pathStack,
onFavChange: () => { this.favVersion++; }, // 跨页同步关键
})
} else if (name === RouteName.ReciteFill) {
ReciteFillPage({ pathStack: this.pathStack })
}
// ... 13 个 case
}
好处:
- 统一的路由参数对象:
router.getParams() as CategoryRouteParam - 统一的返回手势:系统左滑返回直接走
pathStack.pop() - 跨页同步靠 onShown + favVersion:避免 V2 数组重赋值不触发刷新的边角问题
4.3 Service 单例 + Preferences 持久化
所有跨页面状态走 Service 单例,组件不直接读写 Preferences:
class FavoriteServiceImpl {
private cache: Set<string> = new Set();
private loaded = false;
async load(): Promise<void> {
const arr = await Pref.getJSON<string[]>(StorageKey.Favorites, []);
this.cache = new Set(arr);
this.loaded = true;
}
isFav(id: string): boolean {
return this.cache.has(id);
}
async toggle(id: string): Promise<boolean> {
if (this.cache.has(id)) this.cache.delete(id);
else this.cache.add(id);
await Pref.setJSON(StorageKey.Favorites, Array.from(this.cache));
return this.cache.has(id);
}
}
export const FavoriteService = new FavoriteServiceImpl();
Pref 是 PreferencesUtil.ets 封装的同步/异步混合接口,内部 JSON.stringify + flush 一气呵成。10 类 StorageKey 集中管理:
export class StorageKey {
static readonly UserGrade = 'user_grade';
static readonly UserName = 'user_name';
static readonly UserAvatar = 'user_avatar';
static readonly Favorites = 'favorites_v1';
static readonly StudyRecords = 'study_records_v1';
static readonly DailyPlans = 'daily_plans_v1';
static readonly Streak = 'streak_v1';
static readonly Settings = 'settings_v1';
static readonly WrongQuestions = 'wrong_questions_v1';
static readonly DailyGoal = 'daily_goal_v1';
}
命名带
_v1后缀,方便未来 schema 升级时灰度迁移。
4.4 古典美学设计语言
完全自研的"宣纸 + 墨绿 + 朱砂"色板:
{
"color": [
{ "name": "surface", "value": "#F9F7F2" }, // 宣纸底色
{ "name": "surface_card", "value": "#FFFFFF" },
{ "name": "primary", "value": "#436444" }, // 墨绿主色
{ "name": "primary_soft", "value": "#E4EFE4" },
{ "name": "accent", "value": "#B35C5C" }, // 朱砂强调色
{ "name": "text_title", "value": "#2D3436" },
{ "name": "text_body", "value": "#3F4543" },
{ "name": "text_sub", "value": "#737970" }
]
}
字号体系 float.json:fs_caption 12 / fs_body 14 / fs_subtitle 16 / fs_title 18 / fs_headline 22 / fs_poetry 24(专用于诗句)。
诗句一律 serif 字体 + 竖排(emulated with \n + center align),完美贴合古典调性。
4.5 4 种背诵模式的题型抽象
填空 / 选择 / 连线 / 听写 4 种模式表面差异大,核心抽象都是「题面 + 用户输入 + 正确答案 + 校验」。背诵完成时统一调:
// 每个 RecitePage 在答题结束时
await RecordService.add({
poemId, poemTitle,
type: 'recite',
mode: 'choice', // or 'fill' / 'connect' / 'listen'
score, rightCount, wrongCount,
durationSec,
});
RecordService 内部检测 wrongCount > 0 || score < 100,自动派生错题到 WrongQuestionService。一处入口,4 种模式共用。
4.6 等级 + 成就 + 打卡的 @Computed 派生
所有"统计型"数据都不存独立状态,全部 @Computed 派生:
@Computed
get stat(): StudyStat {
const _v = this.favVersion; // 依赖 favVersion 触发重算
return RecordService.stat();
}
@Computed
get levelInfo(): LevelInfo {
return levelOf(this.stat.totalPoems);
}
这样确保:背诵完成 → RecordService 更新 → favVersion++ → @Computed 重算 → 等级/成就 UI 自动刷新。
5、完整数据流分析
以「冷启 → 选诗 → 选模式背诵 → 答错派生错题 → 返回首页看进度」为例:
冷启
│
▼
EntryAbility.onCreate
└─ WindowStage.loadContent('pages/Index')
│
▼
Index.aboutToAppear
├─ FavoriteService.load() / RecordService.load() / WrongQuestionService.load() / PlanService.load()
└─ pathStack 初始化、avatarRef 读取
│
▼
MainTabsPage 显示 → HomeView 默认 active
─────────────────────────────────────────────────────────────────
用户点首页「今日一首」快捷入口
└─ pathStack.pushPathByName(RouteName.PoemDetail, poemId)
│
▼
PoemDetailPage.aboutToAppear
└─ this.poem = PoemService.byId(poemId)
↓ 展示「夏日绝句」+ 注释/译文/赏析/作者 + 3 动作按钮
─────────────────────────────────────────────────────────────────
用户点「开始背诵」
└─ pathStack.pushPathByName(RouteName.ReciteMode, poemId)
│
▼
ReciteModePage 显示 4 种模式 → 用户点「选择题」
└─ pathStack.pushPathByName(RouteName.ReciteChoice, poemId)
─────────────────────────────────────────────────────────────────
ReciteChoicePage 答题
└─ 用户选 B(错) → 第 1 题答错记录 wrongCount++
↓
答完 3 道 → RecordService.add({ type: 'recite', mode: 'choice', wrongCount: 1, ... })
├─ Preferences 落盘
└─ 内部自动派生:WrongQuestionService.addBatch([{ poemId, mode, prompt, userAnswer, correctAnswer }])
├─ 同首诗+同 mode+同 prompt 已存在 → 更新(计数 +1)
└─ 不存在 → 新增 + mastered=false
↓
Preferences 落盘
─────────────────────────────────────────────────────────────────
用户返回 ReciteMode → 返回 PoemDetail → 返回 Home
└─ 每次 onShown → 触发 @Computed 重算 stat / levelInfo
↓
HomeView 顶部「童生 → 秀才」进度条更新
RecordView 错题本数从 0 → 1
AchievementsPage 背诵篇「背诵达人 3/50 → 4/50」更新
观察点:
- 冷启一次性 load 4 个 Service:保证后续读取全部命中内存 cache,UI 渲染零等待。
- 答错自动派生:
RecordService.add内部检测wrongCount > 0自动写错题,业务方完全无感。 - 复合 key 去重:同首诗反复答错同一道题不会堆积,而是更新
lastWrongAt时间戳。 @Computed全链路联动:1 次RecordService.add触发 N 个派生值重算,但每个值只算一次。
6、6 大技术亮点速览
6.1 凹槽凸起底部 Tab 栏(原生 ArkUI 手写)
5 个 Tab:左 2 + 中央凹槽凸起 + 右 2。中央"学习"按钮白色圆形 + 阴影 + 上移制造凸起视觉,凹槽用 Shape + Path SVG 路径切割。
→ 详见第 1 篇文章
6.2 Navigation 路由架构 + 跨页状态同步
单 Navigation 根 + 13 个 NavDestination + onShown 回调 + favVersion 版本号让收藏态从详情页同步回首页 PoemCard。
→ 详见第 2 篇文章
6.3 7 类弹窗在一个项目里
Toast / Popup / Menu / showDialog / showActionSheet / showActionMenu / showTextPickerDialog / openCustomDialog / bindSheet / bindContentCover / OverlayManager —— 全在 wqsy 里用到了不同业务场景。
→ 详见第 3 篇文章
6.4 错题本自动派生 + 题级去重 + 软删除
WrongQuestionService 用 poemId + mode + prompt 复合 key 去重,mastered=true 软删除(保留审计字段)。
→ 详见第 4 篇文章
6.5 5 段等级 + 8 大成就 + 连续打卡
童生→秀才→举人→进士→诗仙 5 段进阶。8 大成就 4 个分类。连续天数算法基于「最近一次打卡时间 - 今天 ≤ 1 天」递推。
→ 详见第 5 篇文章
6.6 零权限头像三合一
卡通预设(cartoon:libai)+ 系统相册 PhotoViewPicker + 系统相机 cameraPicker,全程零权限申请,鸿蒙隐私模型最佳实践。
→ 后续文章
7、上架真实经验
7.1 审核反馈与修复
第一次上架收到 3 个审核 issue:
| 审核问题 | 根因 | 修复 |
|---|---|---|
| ❌ 图标不符合 UX 规范 | EntryAbility 用 $media:foreground 而非 $media:layered_image |
改成分层图标 + 补 background.png + 1024×1024 |
| ❌ 错题本移除后未实时更新 | V2 数组重赋值依赖 Service 引用变化 | 立即本地 filter + [...spread] 双保险刷新 |
| ❌ 我的收藏取消后未实时更新 | 同上 | 同上模式修复 PoemListPage |
| ❌ 意见反馈即将开放 | 该入口未实装功能 | 新建 FeedbackPage + Preferences 持久化 |
修复后 versionName 1.0.1 → 1.0.2,二次提审通过。
7.2 性能保障
- 首屏加载 < 500ms:4 个 Service 冷启并发 load
- 列表滚动稳 60fps:诗词列表用
LazyForEach+key=id - 暗色模式适配:
resources/dark/element/color.json全套色表
8、总结
「古诗学习宝」从 0 到 1 用了约一个月业余时间,基于 HarmonyOS 6 + ArkUI V2 原生实现,关键能力均走系统 Kit:
-
完整产品形态:5 大 Tab + 13 子页面 + 4 种背诵模式 + 错题本 + 打卡 + 等级 + 成就 + 收藏 + 头像系统 + 意见反馈,277 首小学必背古诗全收录。
-
技术栈以系统 Kit 为主:
@ComponentV2状态管理 +Navigation路由 +Preferences持久化 +photoAccessHelper选图,关键能力全部走系统 Kit,源码即贴即用。 -
架构清晰可扩展:「视图 + Service 单例 + 持久化」三层 +
@Computed派生算法,每个 Service 单一职责,跨页面状态唯一源——任何新模块(笔记 / 群学习 / AI 翻译 / 服务卡片)都可在此架构上 30 分钟集成。 -
古典美学设计语言:宣纸色
#F9F7F2+ 墨绿#436444+ 朱砂#B35C5C+ serif 字体 + 国画素材,从颜色到字体到布局都贴合古诗词的氛围。 -
真实上架经验:审核 3 个 issue 全部修复 + 性能保障 + 暗色模式 + 隐私模型,已上架 App 市场。
-
6 大技术亮点值得单独成篇:凹槽 TabBar / Navigation 跨页同步 / 7 类弹窗选型 / 错题本派生 / 等级成就 / 零权限头像 —— 接下来会分篇详解。
🎁 下载体验
**「古诗学习宝」**已上架华为应用市场,搜索 古诗学习宝 即可下载。
- ✅ 完全免费 / 零广告 / 零内购
- ✅ 277 首小学必背古诗全收录,1~6 年级同步课本
- ✅ 4 种背诵模式 + 错题本 + 打卡激励
- ✅ 宣纸色古典美学,专为小学生设计
如果觉得对孩子学习古诗有帮助,烦请帮忙点个五星 🌟,您的好评是我持续投入的最大动力。也欢迎在评论区留下使用反馈或想看的技术细节,我会优先回复并改进。
📚 文中所有截图均来自真机运行,源码托管中(关注作者获取)。
👋 鸿蒙开发者朋友,如果你也在做教育 / 工具类应用,欢迎评论区交流,互相学习。
更多推荐



所有评论(0)