ArkTS急救指南应用开发实战——鸿蒙原生HarmonyOS全流程详解
ArkTS急救指南应用开发实战——鸿蒙原生HarmonyOS全流程详解
运行截图:


前言
在日常生活中,突发意外情况时有发生,掌握基本的急救知识对于每个人来说都至关重要。烫伤、心肺复苏、止血等常见急救场景,普通人往往因缺乏系统性的指导而手忙脚乱。如果能有一款手机应用,在紧急时刻快速提供清晰、结构化的急救步骤指引,将极大提高自救互救的效率。
本文将详细介绍如何使用 ArkTS 语言,在 HarmonyOS(鸿蒙)平台上从零开始开发一款急救指南应用。该应用采用 Grid 网格布局展示急救场景分类(烫伤、心肺复苏、止血),使用 List 列表展示每个场景的详细操作步骤。文章将涵盖项目架构设计、数据模型定义、UI 组件实现、状态管理机制以及编译调试中遇到的实际问题与解决方案,适合对 ArkTS 和 HarmonyOS 开发感兴趣的开发者参考学习。
一、项目概述与技术选型
1.1 项目目标
本项目旨在构建一个轻量级的急救知识指南应用,核心功能包括:
- 急救场景分类展示:通过 Grid 网格卡片,直观展示烫伤、心肺复苏、止血三大常见急救场景。
- 详细步骤指引:点击任意场景卡片后,下方以 List 列表形式逐步展示该场景的完整急救操作流程。
- 关键警告提示:在操作步骤中嵌入红色警告信息,提醒用户避免常见误区。
- 交互状态反馈:选中的场景卡片带有高亮边框和背景色变化,未选择时显示引导提示。
1.2 技术选型
| 技术项 | 选择 | 说明 |
|---|---|---|
| 开发语言 | ArkTS | HarmonyOS 推荐的声明式 UI 开发语言 |
| UI 框架 | ArkUI 声明式范式 | 基于装饰器 + Builder 模式的组件化开发 |
| 布局组件 | Grid + List | Grid 用于分类选择,List 用于步骤详情展示 |
| 状态管理 | @State 装饰器 | 组件内状态管理,驱动 UI 响应式更新 |
| 运行平台 | HarmonyOS NEXT | 鸿蒙原生应用平台 |
1.3 项目结构
ArkTSFirstAd/
├── AppScope/ # 应用级配置
│ └── app.json5 # 应用描述文件
├── entry/ # 主模块
│ └── src/main/
│ ├── ets/
│ │ ├── entryability/
│ │ │ └── EntryAbility.ets # 应用入口 Ability
│ │ └── pages/
│ │ └── Index.ets # 主页面(核心代码)
│ └── resources/ # 资源文件
│ └── base/
│ ├── element/ # 颜色、字符串等基础元素
│ └── media/ # 图片等媒体资源
├── build-profile.json5 # 构建配置
└── oh-package.json5 # 包描述文件
整个应用的核心业务逻辑集中在 entry/src/main/ets/pages/Index.ets 这一个文件中,采用单页面架构实现全部功能,结构简洁明了。
二、数据模型设计
良好的数据模型是应用开发的基础。本项目定义了两个核心接口来描述急救指南的数据结构。
2.1 急救步骤接口 FirstAidStep
interface FirstAidStep {
step: number // 步骤序号
title: string // 步骤标题
description: string // 步骤详细描述
warning?: string // 可选的警告提示信息
}
FirstAidStep 接口描述单个急救操作步骤。其中 warning 字段使用了 TypeScript 的可选属性语法(?),表示该字段不是必须的。只有在步骤中存在需要特别提醒的操作注意事项时,才会提供该字段值。
2.2 急救分类接口 FirstAidCategory
interface FirstAidCategory {
id: number // 分类唯一标识
name: string // 分类名称(烫伤/心肺复苏/止血)
icon: string // 分类图标(Emoji)
color: string // 主题颜色(Hex 色值)
steps: FirstAidStep[] // 该分类下的所有操作步骤
}
FirstAidCategory 接口定义了一个完整的急救场景分类。每个分类拥有独立的主题色、图标和一系列操作步骤。color 字段不仅用于分类卡片的视觉区分,还会贯穿到步骤编号圆圈、选中边框等全局视觉元素中,确保一致的设计语言。
2.3 急救数据定义
项目将所有急救知识以常量数组的形式内联定义在页面文件中,便于开发阶段的快速迭代:
const firstAidData: FirstAidCategory[] = [
{
id: 1,
name: '烫伤',
icon: '🔥',
color: '#FF6B35', // 橙色主题
steps: [
{
step: 1,
title: '脱离热源',
description: '立即远离烫伤源,脱去或剪开覆盖伤口的衣物。',
warning: '切勿强行撕扯粘在皮肤上的衣物'
},
// ... 共 5 个步骤
]
},
{
id: 2,
name: '心肺复苏',
icon: '❤️',
color: '#E63946', // 红色主题
steps: [
// ... 共 6 个步骤
]
},
{
id: 3,
name: '止血',
icon: '🩸',
color: '#A4133C', // 深红色主题
steps: [
// ... 共 6 个步骤
]
}
]
三个分类采用不同的暖色系主题色,既区分了场景,又在视觉上保持了急救主题的统一感。烫伤使用橙色(#FF6B35)传递温暖感,心肺复苏使用标准红色(#E63946)呼应心脏主题,止血使用深红色(#A4133C)暗示血液颜色。
三、页面整体布局架构
3.1 页面结构分析
整个页面从上到下采用 Column 垂直布局,分为四个核心区域:
┌─────────────────────────┐
│ 顶部标题栏 (Row) │ 高度固定 56vp,红色背景
├─────────────────────────┤
│ Grid 分类选择区域 │ 白色背景,高度 100vp
├─────────────────────────┤
│ 分隔线 (Divider) │ stroke 高度 8vp
├─────────────────────────┤
│ │
│ List 步骤详情区域 │ 占满剩余空间
│ (或空状态提示) │
│ │
└─────────────────────────┘
3.2 根容器与主构建方法
@Entry
@Component
struct Index {
@State selectedId: number = -1
@State categories: FirstAidCategory[] = firstAidData
build() {
Column() {
// 顶部标题栏
// Grid 分类区域
// 分隔线
// 详情步骤列表(条件渲染)
}
.width('100%')
.height('100%')
}
}
@Entry 装饰器标记该组件为页面入口组件。@Component 装饰器表明这是一个可复用的 UI 组件。struct Index 是组件的声明,采用值类型(struct)而非引用类型(class),这是 ArkTS 组件声明的标准写法。
四、状态管理机制详解
4.1 @State 装饰器
本应用使用了两个 @State 状态变量来驱动 UI 更新:
@State selectedId: number = -1 // 当前选中的分类 ID,-1 表示未选中
@State categories: FirstAidCategory[] = firstAidData // 急救分类数据
@State 是 ArkUI 框架中最基础的状态管理装饰器。当被 @State 标注的变量发生变化时,框架会自动检测依赖该变量的 UI 组件并触发重新渲染。在本应用中:
selectedId:核心交互状态。当用户点击 Grid 中的分类卡片时,selectedId会被更新为对应分类的id,从而触发build()方法重新执行,下方的 List 区域根据条件渲染逻辑展示对应步骤。categories:数据源状态。在当前实现中数据为静态常量,但保留为@State便于未来扩展为动态加载场景。
4.2 条件渲染逻辑
if (this.selectedId === -1) {
// 显示空状态提示
Column() {
Text('👆')
Text('请在上方选择急救场景')
Text('查看详细操作步骤')
}
} else {
this.DetailListBuilder()
}
这段条件渲染逻辑实现了两个视图的切换:未选择时展示引导提示,选择后展示步骤详情。ArkTS 的声明式语法中 if-else 可以直接在 build() 方法中使用,框架会根据条件自动管理 DOM 节点的创建和销毁。
五、Grid 分类网格实现
5.1 Grid 组件配置
Grid() {
ForEach(this.categories, (item: FirstAidCategory) => {
GridItem() {
this.GridItemBuilder(item)
}
.aspectRatio(1)
})
}
.columnsTemplate('1fr 1fr 1fr') // 3 列等宽
.rowsTemplate('1fr') // 1 行
.columnsGap(12) // 列间距 12vp
.width('100%')
.height(100) // 总高度 100vp
Grid 是 ArkUI 提供的网格布局组件,适合展示固定行列结构的卡片内容。.columnsTemplate('1fr 1fr 1fr') 将可用宽度三等分,每列占据相同比例的空间。.columnsGap(12) 在列与列之间添加 12vp 的间距。.aspectRatio(1) 确保每个 GridItem 为正方形,形成规整的卡片网格。
5.2 GridItemBuilder 构建器
@Builder
GridItemBuilder(item: FirstAidCategory) {
Column() {
Text(item.icon)
.fontSize(36)
Text(item.name)
.fontSize(16)
.fontWeight(FontWeight.Medium)
.fontColor('#333333')
.margin({ top: 8 })
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.backgroundColor(this.selectedId === item.id ? item.color + '18' : '#F7F8FA')
.borderRadius(12)
.border({
width: this.selectedId === item.id ? 2 : 0,
color: item.color
})
.onClick(() => {
if (this.selectedId === item.id) {
this.selectedId = -1 // 再次点击取消选中
} else {
this.selectedId = item.id // 选中该分类
}
})
}
这个 @Builder 方法封装了单个分类卡片的构建逻辑,接收一个 FirstAidCategory 参数。几个关键设计点:
动态背景色:通过三元表达式实现选中/未选中状态的背景色切换。选中状态使用分类主题色叠加 18(十六进制 24)的透明度(item.color + '18'),形成柔和的高亮效果;未选中时使用浅灰色(#F7F8FA)。
动态边框:选中时显示 2px 宽的主题色边框,未选中时边框宽度为 0,完全隐藏。
点击交互:通过 .onClick() 注册点击事件,实现切换选中/取消选中的逻辑。这是一个典型的 toggle 模式——再次点击已选中的卡片会取消选中。
垂直居中:卡片内容通过 .justifyContent(FlexAlign.Center) 实现垂直居中,.width('100%').height('100%') 确保卡片撑满 GridItem 的全部空间。
六、List 步骤详情实现
6.1 DetailListBuilder 构建器结构
@Builder
DetailListBuilder() {
List() {
ForEach(this.categories, (category: FirstAidCategory) => {
if (this.selectedId === category.id) {
ListItem() {
Column() {
// 1. 分类标题区
// 2. 步骤列表(嵌套 ForEach)
// 3. 底部 120 提示
}
}
}
})
}
.width('100%')
.layoutWeight(1)
.backgroundColor('#FAFAFA')
.divider({ strokeWidth: 0 })
}
DetailListBuilder 是页面下半部分的核心构建器。它使用 List 组件包裹步骤内容,通过外层 ForEach 遍历所有分类,再用 if 条件筛选出当前选中的分类进行渲染。
.layoutWeight(1) 使 List 占据 build() 方法中 Column 布局的全部剩余空间。.divider({ strokeWidth: 0 }) 隐藏 List 组件的默认分割线,改为在各步骤之间自定义分割线样式。
6.2 嵌套 ForEach 渲染步骤
ForEach(category.steps, (step: FirstAidStep, index: number) => {
ListItem() {
Column() {
if (index > 0) {
Divider()
.color('#E8E8E8')
.margin({ left: 29, top: 0, bottom: 0 })
}
this.StepItemBuilder(step, category.color)
}
}
})
这里的嵌套 ForEach 是 ArkTS 中处理层级数据的常见模式。外层遍历分类,内层遍历步骤。每个步骤包裹在 ListItem 中,形成 List 的子项。非首个步骤前方添加一条缩进的分割线(左偏移 29vp,与步骤编号圆圈的宽度对齐),营造步骤之间的视觉连接感。
6.3 StepItemBuilder 步骤项构建器
@Builder
StepItemBuilder(step: FirstAidStep, color: string) {
Row() {
// 左侧:步骤编号圆圈
Column() {
Text(step.step.toString())
.fontSize(14)
.fontWeight(FontWeight.Bold)
.fontColor('#FFFFFF')
}
.width(28)
.height(28)
.borderRadius(14)
.backgroundColor(color)
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
// 右侧:步骤内容
Column() {
Text(step.title)
.fontSize(16)
.fontWeight(FontWeight.Medium)
.fontColor('#1A1A1A')
Text(step.description)
.fontSize(14)
.fontColor('#666666')
.margin({ top: 4 })
.lineHeight(20)
// 可选的警告提示
if (step.warning) {
Row() {
Text('⚠')
Text(step.warning!)
.fontColor('#E63946')
}
.backgroundColor('#FFF3F3')
.borderRadius(6)
}
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
.margin({ left: 12 })
}
.width('100%')
.padding({ left: 16, right: 16, top: 12, bottom: 12 })
}
每个步骤项采用 Row 水平布局,左侧为圆形步骤编号,右侧为步骤标题、描述和可选的警告提示。
步骤编号圆圈:宽高 28vp 的正圆,使用分类主题色作为背景,白色粗体数字作为内容。.borderRadius(14)(宽高的一半)确保完美圆形。
警告提示区域:通过 if (step.warning) 条件渲染,仅在步骤存在警告信息时才显示。使用浅红色背景(#FFF3F3)和红色文字(#E63946),搭配警告符号,在视觉上引起用户注意。
布局细节:右侧内容区使用 .alignItems(HorizontalAlign.Start) 左对齐,.layoutWeight(1) 撑满剩余空间,.margin({ left: 12 }) 与编号圆圈保持 12vp 间距。
七、顶部标题栏与空状态设计
7.1 顶部标题栏
Row() {
Text('🏥')
.fontSize(24)
Text('急救指南')
.fontSize(22)
.fontWeight(FontWeight.Bold)
.fontColor('#FFFFFF')
.margin({ left: 8 })
}
.width('100%')
.height(56)
.padding({ left: 20 })
.alignItems(VerticalAlign.Center)
.backgroundColor('#E63946')
标题栏采用红色背景(#E63946)搭配白色文字,形成强烈的视觉识别性。高度固定为 56vp,这是 Material Design 和 HarmonyOS 中标准的顶部栏高度。左侧内边距 20vp,与 Grid 区域的内边距保持一致,形成对齐的视觉节奏。
7.2 空状态提示
Column() {
Text('👆')
.fontSize(48)
.margin({ bottom: 16 })
Text('请在上方选择急救场景')
.fontSize(16)
.fontColor('#999999')
Text('查看详细操作步骤')
.fontSize(14)
.fontColor('#CCCCCC')
.margin({ top: 8 })
}
.width('100%')
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
当用户尚未选择任何急救场景时,页面下方显示一个友好的引导提示。居中的手指指向图标配合灰色文字,清晰地传达"请先选择分类"的交互引导。两级文字使用不同灰度(#999999 和 #CCCCCC)区分主副信息层次。
八、ForEach 与 @Builder 的配合模式
8.1 @Builder 装饰器
@Builder 是 ArkUI 中用于定义可复用 UI 片段的装饰器。与 @Component 不同,@Builder 方法不创建独立的组件实例,而是将构建逻辑内联展开到父组件的渲染树中。
在本应用中,定义了三个 @Builder 方法:
| 构建器名称 | 职责 | 参数 |
|---|---|---|
GridItemBuilder |
构建单个分类卡片 | item: FirstAidCategory |
StepItemBuilder |
构建单个步骤项 | step: FirstAidStep, color: string |
DetailListBuilder |
构建完整的步骤详情列表 | 无(使用组件状态) |
8.2 ForEach 的使用规范
ArkTS 中的 ForEach 方法接收三个参数:
ForEach(
arr: Array, // 数据源数组
(item: T, index: number) => void, // 项构建函数
(item: T) => string // 可选的 key 生成函数
)
在本项目中,外层 ForEach 使用 categories 数组,内层 ForEach 使用 category.steps 数组。每层 ForEach 的 item 构建函数中都通过 this 引用组件的 @Builder 方法来构建具体 UI。
8.3 开发中遇到的关键问题
在实际开发过程中,遇到一个典型的编译错误:
ERROR: Property 'width' does not exist on type 'void'
这个问题出现在尝试对 @Builder 方法的调用结果进行链式属性调用时:
// 错误写法
this.DetailListBuilder()
.width('100%')
.layoutWeight(1)
.backgroundColor('#FAFAFA')
原因分析:在 ArkTS 中,@Builder 方法的返回类型是 void,它不会返回可操作的组件对象。因此,不能在调用 @Builder 方法后继续链式调用 .width() 等组件属性方法。
解决方案:将需要的属性设置移入 @Builder 方法内部的顶层组件上:
// 正确写法
@Builder
DetailListBuilder() {
List() {
// ... 内容
}
.width('100%') // 属性写在 Builder 内部
.layoutWeight(1)
.backgroundColor('#FAFAFA')
}
// 调用处不再链式调用
this.DetailListBuilder()
这是 ArkTS 开发中一个常见且容易踩坑的细节,对于熟悉 React 或 Vue 等前端框架的开发者尤其需要注意——@Builder 不是返回 JSX 元素的函数,而是直接操作渲染树的构建器。
九、颜色系统与视觉设计
9.1 配色方案
应用整体采用红色系为主色调,契合"急救"主题:
| 用途 | 色值 | 说明 |
|---|---|---|
| 标题栏背景 | #E63946 | 标准急救红 |
| 烫伤主题色 | #FF6B35 | 橙色,传递热源感知 |
| 心肺复苏主题色 | #E63946 | 红色,对应心脏主题 |
| 止血主题色 | #A4133C | 深红色,对应血液 |
| 步骤背景 | #FAFAFA | 极浅灰,区分信息层级 |
| 未选中卡片背景 | #F7F8FA | 冷灰色 |
| 选中卡片背景 | {color}18 |
主题色 10% 透明度叠加 |
| 警告背景 | #FFF3F3 | 浅红底色 |
| 警告文字 | #E63946 | 标准警告红 |
| 主标题文字 | #1A1A1A | 近黑色 |
| 副标题文字 | #333333 | 深灰 |
| 说明文字 | #666666 | 中灰 |
| 引导文字 | #999999 | 浅灰 |
| 辅助文字 | #CCCCCC | 极浅灰 |
9.2 间距系统
应用采用一致的间距规范:
- 页面级外边距:16vp(Grid 区域和步骤内容区)
- 卡片内边距:居中对齐,通过 Flex 布局自动分配
- 标题栏内边距:左 20vp,与 Grid 区域形成视觉对齐
- 步骤项内边距:左右 16vp,上下 12vp
- 元素间距:8vp(小间距)、12vp(中间距)、16vp(大间距)
十、底部 120 提示与安全保障
Row() {
Text('如遇紧急情况请立即拨打 ')
.fontSize(13)
.fontColor('#999999')
Text('120')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#E63946')
}
.width('100%')
.justifyContent(FlexAlign.Center)
.padding(16)
在每个急救场景的步骤列表底部,都固定显示"如遇紧急情况请立即拨打 120"的提示。数字"120"使用加粗红色字体突出显示,确保用户在任何情况下都能快速找到急救电话信息。这个设计体现了急救应用的核心原则——生命安全永远是第一位的,应用中的知识仅供参考,不能替代专业医疗救助。
十一、开发环境与编译运行
11.1 环境要求
开发本应用需要以下环境配置:
- IDE:DevEco Studio 5.0+(HarmonyOS NEXT 专用 IDE)
- SDK:HarmonyOS NEXT SDK
- 语言:ArkTS(基于 TypeScript 扩展)
- Node.js:16+ (用于 hvigor 构建工具链)
11.2 编译与运行
- 在 DevEco Studio 中打开项目
- 等待 hvigor 自动同步依赖
- 连接 HarmonyOS 模拟器或真机设备
- 点击 Run 按钮或执行
hvigorw assembleHap命令 - 编译成功后自动安装并启动应用
11.3 常见编译错误处理
在开发过程中,以下是需要特别注意的 ArkTS 编译规范:
@Builder 返回值问题:如前文所述,@Builder 方法返回 void,不可链式调用组件属性。
类型安全要求:ArkTS 是 TypeScript 的严格超集,所有变量必须有明确类型声明。例如 @State selectedId: number = -1 必须显式标注 number 类型。
空值处理:可选属性访问需要使用 ! 非空断言操作符(如 step.warning!),或使用 if 条件判断后访问。
十二、功能扩展与优化方向
当前应用作为急救指南的基础版本已经具备核心功能,以下是一些可以进一步探索的优化方向:
12.1 数据持久化
将急救知识数据从内联常量迁移至本地 JSON 文件或轻量级数据库(如 relationalStore),支持后续运营更新内容而无需重新编译发版。
12.2 多媒体辅助
为每个急救步骤添加示意图或短视频指引,利用 Image 和 Video 组件实现更直观的操作演示。可以将图片资源放在 resources/base/media/ 目录中,通过 $r('app.media.xxx') 引用。
12.3 搜索功能
在顶部添加搜索栏,支持用户通过关键词快速定位到对应的急救步骤,提升紧急情况下的检索效率。
12.4 收藏与历史记录
添加"收藏"功能,允许用户将常用的急救场景加入收藏夹;添加"最近查看"历史记录,方便快速回访。
12.5 无障碍适配
添加 accessibilityText 属性和焦点管理,支持屏幕阅读器(VoiceOver/TalkBack)朗读,确保视障用户也能获取急救信息。
12.6 深色模式适配
当前应用仅定义了浅色主题,可以通过定义 dark 模式的颜色变量,结合 @StorageProp 或 media query 实现系统级深色模式的自动切换。
十三、ArkTS 声明式 UI 开发心得
通过本项目的实践,总结几点 ArkTS 声明式 UI 开发的核心要点:
声明式思维:ArkTS 采用类似 SwiftUI 和 Jetpack Compose 的声明式 UI 范式。开发者只需要描述"UI 应该是什么样子",而不需要手动操作 DOM 或 View 树。框架会自动计算差异并更新界面。
Builder 模式:@Builder 是 ArkTS 中实现 UI 代码复用的主要手段。将可复用的 UI 片段提取为 @Builder 方法,既保持了代码的可读性,又避免了组件创建的开销。
状态驱动 UI:@State 状态变量是 UI 更新的唯一触发源。所有 UI 变化都应该通过修改状态变量来驱动,而非手动调用刷新方法。
组合优于继承:ArkTS 鼓励通过组合 @Builder 方法来构建复杂界面,而非通过类继承来扩展组件能力。这种模式更灵活、更易于维护。
类型安全:作为 TypeScript 的严格超集,ArkTS 强制类型检查。虽然增加了编码时的类型声明工作量,但有效减少了运行时错误,提升了代码质量。
十四、总结
本文从零开始,详细介绍了使用 ArkTS 开发鸿蒙原生急救指南应用的完整过程。从项目结构设计、数据模型定义,到 Grid 网格分类展示、List 步骤详情列表的实现,再到状态管理、视觉设计和编译调试中的问题解决,涵盖了 HarmonyOS 应用开发的方方面面。
该急救指南应用虽然代码量不大(约 290 行),但完整展示了 ArkTS 声明式 UI 开发的核心模式:@State 驱动响应式更新、@Builder 实现组件复用、ForEach 处理列表渲染、条件渲染实现视图切换。这些都是 HarmonyOS 应用开发的基础能力。
掌握这些基础知识后,开发者可以进一步探索更多高级特性,如 Navigation 路由跳转、网络请求、本地数据持久化、分布式能力等,构建更加丰富的鸿蒙原生应用。急救知识的传播本身就是一个有意义的事业,希望本文的分享能够帮助更多开发者投入到 HarmonyOS 生态的建设中来。
声明:本文中的急救操作步骤仅供参考学习,在实际紧急情况下请务必第一时间拨打 120 急救电话,听从专业医护人员的指导。
项目信息
- 开发语言:ArkTS
- 开发框架:ArkUI 声明式 UI
- 目标平台:HarmonyOS NEXT
- 核心组件:Grid、List、ForEach、@Builder、@State
- 源代码文件:
entry/src/main/ets/pages/Index.ets
更多推荐



所有评论(0)