【OpenHarmony/HarmonyOs 】ArkTS 实现本地化学习 App:元素周期表、方程式与知识库设计

这篇文章基于我的 HarmonyOS 化学学习项目「化学视界」整理。项目的定位很明确:做一款离线可用、打开即学、适合中学生和化学爱好者使用的学习工具。它包含元素周期表、化学方程式、化学知识库、挑战练习、收藏、错题、成就和学习统计等功能。📚

一、我为什么选择“本地化学习 App”这个方向?

一开始做这个项目时,我没有先考虑复杂的账号体系、云同步或推荐系统,而是先问了一个更基础的问题:一个化学学习工具最核心的价值是什么?

我的答案是:查得快、看得懂、练得起来。

所以项目最早的设计重点放在三类内容:

  • ⚛️ 元素周期表:承载 118 个元素的信息查询。
  • ⚗️ 化学方程式:承载常见反应、条件、现象和说明。
  • 📚 化学知识库:承载概念、定律、实验、周期律、有机化学等内容。

这些内容本身非常适合本地化。用户打开 App 后,不需要等网络请求,不需要登录,也不需要担心学习资料突然加载失败。

二、项目整体功能拆分

我在开发时没有把所有逻辑都堆到首页,而是按学习场景拆成多个页面:

  • Index.ets:底部导航主框架。
  • PeriodicTable.ets:元素周期表。
  • ElementDetail.ets:元素详情。
  • Equations.ets:方程式列表。
  • EquationDetail.ets:方程式详情。
  • Knowledge.ets:知识库列表。
  • KnowledgeDetail.ets:知识详情。
  • Quiz.ets:挑战练习。
  • Favorites.ets:收藏夹。
  • Achievement.ets:成就系统。
  • Settings.ets:我的页面和数据管理。

这样的拆法有一个好处:每个页面都围绕一个学习动作展开。查元素就是查元素,刷题就是刷题,收藏就是收藏,后续维护时也不容易混乱。

三、数据层:先把模型设计清楚

本地化 App 最重要的是数据结构。比如元素模型就不是只存一个名字,而是要覆盖学习时真正会查的信息:

export interface ChemicalElement {
  number: number;
  symbol: string;
  name: string;
  nameEn: string;
  atomicMass: string;
  category: ElementCategory;
  electronConfig: string;
  electronegativity: number;
  density: string;
  meltingPoint: string;
  boilingPoint: string;
  discoveryYear: string;
  discoverer: string;
  description: string;
  row: number;
  col: number;
}

我开发时的思路是:列表页需要展示“轻信息”,详情页需要展示“完整信息”。所以模型字段要一次设计完整,页面再按需要取用。

类似地,方程式数据也包含名称、反应式、类型、条件、现象和说明:

export interface ChemicalEquation {
  id: number;
  name: string;
  equation: string;
  type: EquationType;
  conditions: string;
  现象: string;
  description: string;
  level: string;
}

这样做之后,页面就不会被迫把展示文案写死在组件里,后续增加内容也只需要维护数据文件。

四、主框架:底部导航承载高频入口

项目主框架使用 Tabs 承载多个一级入口:

Tabs({ controller: this.tabController, index: this.currentIndex }) {
  TabContent() {
    EquationsView()
  }
  .tabBar(this.tabBarBuilder(0, '方程式',
    $r('app.media.icon_equation_selected'),
    $r('app.media.icon_equation_normal')))

  TabContent() {
    PeriodicTableView()
  }
  .tabBar(this.tabBarBuilder(2, '周期表',
    $r('app.media.icon_periodic_selected'),
    $r('app.media.icon_periodic_normal')))
}
.barPosition(BarPosition.End)
.barMode(BarMode.Fixed)

我没有做一个很重的首页,因为这个 App 是工具型学习产品。用户打开后大概率是要查资料或练习,而不是看欢迎页。

底部导航的顺序也是按使用场景安排的:

  • 方程式:学习化学时经常查。
  • 成就:提供学习激励。
  • 周期表:核心查询工具。
  • 知识:系统学习内容。
  • 挑战:练习与巩固。
  • 收藏:复习入口。
  • 我的:统计和设置。

五、列表页:搜索和筛选是核心能力

方程式和知识库页面都做了搜索与分类筛选。以知识库为例:

Search({ placeholder: '搜索知识点(标题、内容、标签)' })
  .onChange((value: string) => {
    this.searchText = value;
    if (value.length > 0) {
      this.displayedKnowledge = searchKnowledge(value);
      this.isSearchMode = true;
    } else {
      this.updateDisplayedKnowledge();
      this.isSearchMode = false;
    }
  })

开发时我把搜索状态单独抽出来:

  • searchText:当前输入内容。
  • isSearchMode:是否处于搜索模式。
  • displayedKnowledge:最终显示的数据。
  • selectedCategory:当前筛选分类。

这样 UI 层只关心 displayedKnowledge,不需要每次渲染都临时计算。

六、详情页:用参数路由连接列表和内容

元素详情页通过路由参数加载具体元素:

let params = router.getParams() as Record<string, number>;
if (params && params.elementNumber) {
  let el = getElementByNumber(params.elementNumber);
  if (el) {
    this.element = el;
    this.elementLocal = el;
  }
}

我的开发思路是:列表只负责展示摘要和入口,详情页负责完整阅读。这样不会让列表卡片变得臃肿,也能让用户快速扫视。

方程式详情和知识详情也是同样思路:

  • 列表页传 id
  • 详情页根据 id 查本地数据。
  • 找不到数据时展示空状态。

这种方式很适合离线 App,因为数据都在本地,跳转和加载都很快。

七、视觉体验:不同内容使用不同颜色语言

化学内容天然有分类感,比如元素类别、反应类型、知识类型都可以用颜色辅助识别。

方程式页面中,不同反应类型对应不同颜色:

getTypeColor(type: EquationType): string {
  const colorMap: Record<string, string> = {
    'combination': '#E3F2FD',
    'decomposition': '#E8F5E9',
    'replacement': '#FFF3E0',
    'exchange': '#F3E5F5',
    'combustion': '#FFEBEE'
  };
  return colorMap[type] || '#F5F5F5';
}

这种设计不是单纯为了好看,而是为了让学生在视觉上建立关联:看到颜色就能大致判断内容类别。

八、我开发这个项目时的几个取舍

1. 先做离线,再考虑扩展

我没有一开始就做复杂服务端,因为化学资料查询本身就很适合本地化。先把核心学习体验做好,比先做一堆账号和网络能力更重要。

2. 先做可读性,再做复杂动效

元素、方程式和知识库都是内容型页面,动效只做点击反馈、页面进入和弹窗过渡,不让动画抢走阅读注意力。

3. 先统一数据结构,再做页面

如果数据模型混乱,后面做搜索、收藏、详情跳转都会很难。所以我先把元素、方程式、知识点这些模型定好,再开发页面。

九、可以继续优化的方向

后续这个本地化架构还可以继续升级:

  • 增加学习路线,比如“初中基础路线”“高中提升路线”。
  • 给知识点和题目建立关联。
  • 方程式详情中加入反应类型图解。
  • 周期表支持更多筛选条件。
  • 收藏夹支持自定义分组。
  • 本地学习报告增加趋势图。

十、总结

这个项目的核心开发思路可以概括为:

  • 📦 内容本地化,保证打开即用。
  • 🧱 页面模块化,降低维护成本。
  • 🔍 搜索筛选优先,提升查询效率。
  • 📖 列表和详情分离,保证阅读体验。
  • 🎨 用颜色表达分类,帮助用户理解。

对于学习类 App 来说,技术实现不只是把页面写出来,更重要的是把“用户怎么学”变成清晰的信息架构。「化学视界」正是围绕这个目标一步步搭起来的。✨

img

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐