欢迎光临
我们一直在努力

【共创季稿事节】用 HarmonyOS ArkUI 构建「公式速查」APP

用 HarmonyOS ArkUI 构建「公式速查」App:从零到一开发手记

一、前言

作为一名开发者和曾经的理科生,我深知中小学阶段数学、物理、化学公式记忆的痛点。每到考试前,学生们总要翻遍课本和笔记,手忙脚乱地寻找某个公式。能不能做一个轻量、快速、随时可查的公式速查工具呢?恰好最近在接触 HarmonyOS 生态,便萌生了用 ArkUI 开发一个「公式速查」应用的念头。

本文将从项目初始化、数据建模、UI 设计、编译构建等完整流程,详细记录这款应用的开发全过程。无论你是 HarmonyOS 新手还是有一定经验的开发者,都能从中获得一些实用的开发思路和技巧。

二、项目背景与目标

2.1 为什么要做这个 App

中小学教育阶段,公式是理科学习的核心工具。数学中的勾股定理、一元二次方程求根公式,物理中的欧姆定律、牛顿第二定律,化学中的物质的量浓度、pH 值计算——这些公式几乎贯穿了整个中学学习周期。然而,多数学生面临的问题不是"不会用",而是"记不住"或"找不到"。市面上的公式类 App 要么过于臃肿,要么广告繁多,要么需要联网才能使用。

因此,我们决定开发一款纯净、离线、轻量的公式速查应用。

2.2 目标用户

  • 小学高年级学生(需要基础几何、单位换算等)
  • 初中生(数学、物理、化学全套公式需求最旺盛的阶段)
  • 高中生(进阶公式、三角函数、电学、化学反应等)
  • 教师和家长(辅助教学和辅导使用)

2.3 核心功能需求

  • 分类浏览:按学科(数学 / 物理 / 化学)分类,每个学科下设子分类
  • 公式详情:每条公式展示名称、表达式、文字说明和参数解释
  • 离线可用:所有数据本地存储,无需联网
  • 快速导航:一级页面选择学科,二级页面浏览公式列表,支持返回
  • 三、技术选型与项目初始化

    3.1 为什么选择 HarmonyOS + ArkUI

    选择 HarmonyOS 平台主要基于以下考虑:

    第一,生态趋势。 鸿蒙生态正在快速成长,越来越多的设备和用户接入。开发鸿蒙原生应用,是技术储备也是市场先机。

    第二,ArkUI 声明式语法。 ArkUI 采用类 SwiftUI / Jetpack Compose 的声明式 UI 风格,使用 TypeScript 的超集 ArkTS 作为开发语言。对于熟悉前端或现代移动端开发的工程师来说,上手门槛极低。

    第三,一次开发多端部署。 HarmonyOS 的应用可以运行在手机、平板、智慧屏等多种设备上,公式速查这种工具类应用天然适合多端覆盖。

    3.2 开发环境

    • 操作系统:Windows 11
    • IDE:DevEco Studio(鸿蒙官方 IDE,基于 IntelliJ)
    • SDK 版本:HarmonyOS SDK 6.1.0(对应 API Version 12)
    • 构建工具:Hvigor(鸿蒙项目构建工具)
    • 目标 API:API 24(Android 兼容性层面),实际基于 HarmonyOS API 12

    3.3 项目初始化

    通过 DevEco Studio 新建项目,选择"Empty Ability"模板,使用 Stage 模型(即 HarmonyOS 推荐的应用模型)。项目的核心结构如下:

    AppScope/
    app.json5 ← 全局应用配置
    entry/
    build-profile.json5 ← 模块构建配置
    src/main/
    ets/
    entryability/ ← Ability(类似 Android 的 Activity)
    pages/ ← 页面文件
    module.json5 ← 模块清单
    resources/ ← 资源文件

    这里需要解释一下 Stage 模型。它类似于 Android 的组件化架构,每个 Ability 是一个独立的功能单元,页面通过路由跳转实现导航。相比于老的 FA(Feature Ability)模型,Stage 模型更加灵活,资源管理更清晰。

    四、数据模型设计

    4.1 数据结构规划

    公式数据的特点是层级清晰、结构稳定。我们需要设计三级数据模型:

    学科(数学 / 物理 / 化学)
    └── 子分类(代数基础、几何图形、三角函数……)
    └── 公式条目(名称、表达式、说明、参数说明)

    对应的 ArkTS 接口定义如下:

    // 公式条目
    export interface FormulaItem {
    name: string; // 公式名称,如"勾股定理"
    expression: string; // 公式表达式,如"a² + b² = c²"
    desc: string; // 文字说明,解释公式含义
    params: string; // 参数说明,解释每个符号的意义
    }

    // 公式分类(子分类)
    export interface FormulaCategory {
    title: string; // 分类标题,如"几何图形"
    items: FormulaItem[]; // 该分类下的公式列表
    }

    主页面上的学科数据通过一个 CategoryEntry 接口来管理:

    interface CategoryEntry {
    icon: string; // 图标 emoji
    title: string; // 学科名称
    sub: string; // 子标题说明
    color: string; // 主题色
    }

    4.2 公式数据收录情况

    在数据收集阶段,我们参考了人教版、北师大版等主流教材目录,确保覆盖中小学阶段的常用公式。最终收录:

    学科子分类数公式总数
    数学 3 36
    物理 4 38
    化学 4 24
    合计 11 98

    每个公式条目都经过仔细校对,确保表达式准确、描述清晰易懂。

    4.3 数据文件组织

    我们将所有数据集中放在 model/FormulasData.ets 文件中,以常量数组的形式导出。这样做的好处是:

  • 数据即代码:修改数据不需要额外的数据库或网络请求
  • 类型安全:ArkTS 的静态类型检查可以避免数据结构错误
  • 零依赖:应用可以完全离线运行,无需加载耗时
  • 当然,如果公式数量扩展到上千条,后续可以考虑引入 JSON 文件或轻量数据库(如关系型数据库 RDB)。

    五、页面设计与实现

    5.1 整体导航架构

    应用采用两级导航:

    首页(Index.ets)──点击学科卡片──→ 分类详情页(CategoryPage.ets)

    使用 @ohos.router 模块进行页面跳转。路由配置在 main_pages.json 中注册:

    {
    "src": [
    "pages/Index",
    "pages/CategoryPage"
    ]
    }

    5.2 首页设计:三大学科入口

    首页的设计思路是简洁直观。顶部是一个深蓝色的标题栏,显示"公式速查"和副标题"中小学常用公式大全"。下方是三个学科卡片,使用不同的主题色区分:

    • 数学(蓝色 #4A90D9)
    • 物理(橙色 #E67E22)
    • 化学(绿色 #27AE60)

    每个卡片展示学科图标(Emoji)、名称、包含的子分类说明,以及一个"查看全部 →"的引导文字。卡片采用圆角 + 阴影设计,视觉上层次分明。

    ArkUI 中实现卡片非常直接,使用 Stack 作为容器,内部用 Column 布局文本内容,通过 backgroundColor 和 .borderRadius() 设置样式。

    Stack() {
    Column() {
    Text(item.icon).fontSize(44)
    Text(item.title).fontSize(20).fontWeight(FontWeight.Bold).fontColor(Color.White)
    Text('查看全部 →').fontSize(13).fontColor('#AAFFFFFF')
    }
    }
    .width('100%').height(180)
    .backgroundColor(item.color as string)
    .borderRadius(20)
    .shadow({ radius: 8, color: (item.color as string) + '60', offsetY: 4 })

    底部有一段提示文字,说明应用覆盖的范围,让用户一目了然。

    5.3 分类详情页:公式浏览

    当用户点击某个学科卡片时,通过 router.pushUrl() 跳转到 CategoryPage,同时携带学科参数(图标、名称、主题色)。详情页根据参数动态加载对应的公式数据。

    详情页的顶部是一个可返回的标题栏,左侧显示"←"返回按钮和学科名称,背景色与学科主题色一致,形成视觉延续。

    主内容区域是一个可滚动的列表,按照子分类分组展示:

    • 子分类标题:如"📐 代数基础",使用稍大的粗体字
    • 公式卡片:每个公式占一个白色圆角卡片,从上到下依次为公式名称、公式表达式(带浅灰背景高亮)、文字说明、参数说明

    这种设计参考了卡片式 UI 的最佳实践——信息层级清晰,视觉节奏舒适。每个公式卡片中,公式表达式使用了加粗的主题色字体,使其在页面中一目了然。

    5.4 页面间的数据传递

    ArkUI 中页面间传递数据需要使用 router.pushUrl() 的 params 参数。由于 ArkTS 对类型安全要求严格,我们传递的是简单的基本类型参数(字符串),在目标页面通过 router.getParams() 接收。

    // 发送方
    router.pushUrl({
    url: 'pages/CategoryPage',
    params: {
    categoryIcon: item.icon,
    categoryTitle: item.title,
    categoryColor: item.color
    }
    });

    // 接收方
    aboutToAppear(): void {
    const params = router.getParams() as Record<string, string>;
    if (params) {
    this.categoryTitle = params['categoryTitle'] || '公式';
    // … 根据 title 加载对应数据
    }
    }

    这里有一个值得注意的点:aboutToAppear 是组件的生命周期方法,在页面即将显示时调用。我们在这个方法中解析路由参数,并根据 categoryTitle 的值决定加载哪套公式数据。

    六、ArkTS 开发的注意事项

    6.1 严格类型系统

    ArkTS 对类型安全的要求比普通 TypeScript 更加严格——通过编译时的严格检查,减少运行时的意外错误。

    问题一:对象字面量不能用作类型声明

    这是 ArkTS 和标准 TypeScript 最明显的区别之一。在 TypeScript 中可以写 const items: { id: number }[] = […],但在 ArkTS 中必须显式定义接口:

    // ArkTS — 必须显式声明接口
    interface CategoryEntry {
    icon: string;
    title: string;
    sub: string;
    color: ResourceColor;
    }

    private categories: CategoryEntry[] = [
    { icon: '📐', title: '数学公式', sub: '代数 · 几何 · 三角', color: '#4A90D9' }
    ];

    问题二:Grid 组件只接受 GridItem 子组件

    直接往 Grid 里放 Stack 是不行的。解决方案是用 GridItem 包裹,或改用 Column + ForEach:

    // ✅ 用 GridItem 包裹,或改用 Column
    Column() {
    ForEach(this.categories, (item) => {
    Stack() { }.margin({ bottom: 16 })
    })
    }

    在我的实现中选择了 Column + ForEach,因为页面只有三个卡片,Column 更简洁。

    6.2 模块导入规则

    HarmonyOS SDK 6.1.0 中,一些 API 的导入路径发生了变化。例如 router 模块:

    // ✅ 正确(SDK 6.1.0)
    import router from '@ohos.router';

    // ❌ 错误
    import { router } from '@kit.AbilityKit';
    import { router } from '@ohos.router';

    从这个错误可以看出,HarmonyOS 的 Kit 体系在不断演进中。@kit.AbilityKit 是较新的模块组织方式,但并非所有 API 都已经迁移过去。在实际开发中,建议以 DevEco Studio 的代码提示为准。

    另外需要注意的是,不同的导入方式对应不同的用法:

    // 默认导入 — import router from '@ohos.router'
    router.pushUrl({ url: 'pages/CategoryPage', params: {} });

    // 命名导入在某些模块中也是可以的
    import { BusinessError } from '@kit.BasicServicesKit';

    6.3 生命周期理解

    ArkUI 组件的生命周期与 Android 的 Activity 有相似之处。在本次开发中,主要用到以下回调:

    生命周期方法触发时机典型用途
    aboutToAppear 组件即将显示 初始化数据、解析路由参数
    aboutToDisappear 组件即将销毁 清理资源
    build 每次渲染 描述 UI 结构

    注意 build 会被频繁调用(每次状态变量变化时),因此不要在 build 中执行耗时操作。数据初始化应放在 aboutToAppear 中:

    aboutToAppear(): void {
    const params = router.getParams() as Record<string, string>;
    if (params) {
    this.categoryTitle = params['categoryTitle'] || '公式';
    }
    if (this.categoryTitle === '数学公式') {
    this.categories = mathCategories;
    } else if (this.categoryTitle === '物理公式') {
    this.categories = physicsCategories;
    } else if (this.categoryTitle === '化学公式') {
    this.categories = chemistryCategories;
    }
    }

    七、ArkUI 组件详解

    7.1 Column 与 Row:布局基础

    ArkUI 的布局体系基于弹性盒模型(Flexbox),与 CSS Flexbox 类似。

    • Column:垂直排列子组件(相当于 flex-direction: column)
    • Row:水平排列子组件(相当于 flex-direction: row)
    • Stack:层叠排列子组件

    7.2 Scroll:可滚动容器

    Scroll 只接受一个子组件。配合 .layoutWeight(1) 可以让 Scroll 占据父容器的剩余高度空间:

    Scroll() {
    Column() { /* 所有需要滚动的内容 */ }
    }
    .width('100%')
    .layoutWeight(1)

    7.3 Text 与字体样式

    Text('公式速查')
    .fontSize(28)
    .fontWeight(FontWeight.Bold)
    .fontColor(Color.White)
    .textAlign(TextAlign.Center)

    字号单位 fp 是 HarmonyOS 特有的字体像素单位,跟随系统字体缩放自动调整,类似 Android 的 sp。

    7.4 @Builder:复用 UI 片段

    使用 @Builder 提取重复的 UI 单元(如公式卡片),做到一处修改全局生效:

    @Builder FormulaCard(item: FormulaItem) {
    Column() {
    Text(item.name).fontSize(16).fontWeight(FontWeight.Medium)
    Text(item.expression).fontSize(18).fontWeight(FontWeight.Bold)
    // …
    }
    }

    7.5 @State:响应式状态管理

    @State 装饰器是 ArkUI 响应式编程的核心。被 @State 标记的变量发生变化时,自动触发 UI 重新渲染:

    @State categories: FormulaCategory[] = [];
    this.categories = mathCategories; // 视图自动更新

    这种"状态驱动视图"的模式大大减少了手动操作 UI 的代码量。

    八、资源与样式管理

    8.1 资源文件组织

    HarmonyOS 资源按限定词目录组织。本应用使用了以下资源:

    resources/
    base/
    element/
    color.json ← 颜色定义
    float.json ← 尺寸定义
    string.json ← 字符串定义
    media/ ← 图片资源
    profile/
    main_pages.json ← 路由配置

    8.2 主题色设计

    • 首页标题栏:深蓝色 #2C3E50
    • 数学卡片:蓝色系 #4A90D9
    • 物理卡片:橙色系 #E67E22
    • 化学卡片:绿色系 #27AE60
    • 背景:浅灰色 #F5F6FA

    8.3 字体与排版

    公式排版采用以下策略:

  • 使用 Unicode 字符直接表示特殊符号(²、³、√、π、θ 等)
  • 公式表达式使用稍大的字号(18fp)和加粗样式
  • 公式区域增加浅灰背景(#F0F4F8)和圆角,与说明文字区分
  • Unicode 方案的呈现效果虽不如 LaTeX 专业,但对中小学阶段的公式展示已经足够,且避免了额外依赖。

    九、构建与部署

    9.1 构建流程

    HarmonyOS 使用 Hvigor 构建工具,类似 Android 的 Gradle:

    hvigorw assembleHap –mode module -p module=entry@default -p product=default

    构建流程包括:PreBuild → ProcessProfile → CompileResource → CompileArkTS → PackageHap → SignHap。

    9.2 遇到的构建问题

    ArkTS 语法检查严格:对象字面量不能作为类型声明、数组需可推断类型——通过定义显式接口解决。

    组件类型限制:Grid 组件只接受 GridItem 子组件,需要 GridItem 包裹。

    资源名称冲突:AppScope 和 entry 模块定义同名资源会产生冲突警告。应只在 AppScope 放全局资源,模块特有资源放各自目录。

    十、应用截图与功能演示

    使用流程非常直观:启动 → 选择学科 → 浏览公式列表 → 查看公式详情 → 返回。整个过程无需联网,零等待。

    十一、总结与展望

    11.1 开发心得

    通过这个项目,深入体验了 HarmonyOS 应用开发的完整流程。ArkUI 的声明式 UI 风格提升了开发效率——状态驱动视图更新,避免手动操作 DOM 的繁琐。ArkTS 的严格类型系统虽然在初期带来编译报错,但从长期维护看,类型安全能减少运行时错误。

    11.2 可扩展方向

  • 搜索功能:支持公式名称或关键词全文搜索
  • 收藏功能:收藏常用公式,快速访问
  • 公式推导:为复杂公式增加推导过程
  • 题目示例:每个公式配典型例题
  • 深色模式:适配夜间使用
  • 多端适配:利用 HarmonyOS 多端部署能力适配平板等设备
  • 11.3 源码获取

    项目源码结构清晰,可在 DevEco Studio 中直接打开运行。所有公式数据集中在 model/FormulasData.ets 文件中,方便后续扩充。

    十二、写在最后

    开发工具类应用最大的成就感不在于技术的复杂度,而在于产品真正能帮到人。"公式速查"虽然功能简单,但它解决的是一个真实的需求——让学生能够在几秒内找到需要的公式,节省翻书的时间,把更多精力用在理解和应用上。

    作为一名开发者,能够用自己的技术为教育做一点微小的贡献,是一件很有意义的事。

    如果你也在学习 HarmonyOS 开发,希望这篇博客对你有所帮助。欢迎交流你的开发心得和改进建议!


    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    。*

    赞(0)
    未经允许不得转载:171主机测评 » 【共创季稿事节】用 HarmonyOS ArkUI 构建「公式速查」APP
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址