鸿蒙ArkTS原生用药提醒 - 多药物管理 健康管理助手

1. 应用概述
药物提醒(MedicineReminder)是一款基于HarmonyOS ArkTS框架开发的健康管理工具,其核心功能是帮助用户设置服药时间提醒、管理药物清单、记录服药状态。这款应用将传统的服药管理方式数字化,提供直观的药物添加、提醒时间设置和服药记录功能,为用户的用药安全管理提供有力支持。
在技术实现层面,药物提醒应用充分展示了HarmonyOS声明式UI开发范式的核心能力。通过@State装饰器实现响应式状态管理,TextInput组件实现药物名称和时间输入,List组件实现药物清单渲染,Button组件实现交互操作,以及清晰的卡片式UI设计,构成了一个功能聚焦的用药管理助手应用。应用的代码结构简洁清晰,使用HarmonyOS原生API完成所有功能实现,没有引入任何复杂的第三方依赖。
本技术博客将从应用架构设计、核心代码实现、数据模型设计、状态管理机制、List组件使用、提醒时间设计以及健康管理类应用设计要点等多个维度,对这款药物提醒应用进行全面的技术剖析。通过本文的深入讲解,读者不仅能够理解如何实现一个功能完善的药物提醒应用,更能够掌握HarmonyOS ArkTS开发中的核心知识点,特别是TextInput输入处理、List列表渲染、状态管理、提醒机制以及健康管理类应用的设计要点等关键技术点。
2. 技术架构分析
2.1 整体架构设计
药物提醒应用采用了单页面架构(Single Page Application),整个应用仅包含一个主页面,通过组件化设计将UI展示与业务逻辑进行有效分离。从代码组织角度来看,应用主要分为以下几个核心部分:页面入口组件(MedicineReminder)、通用标题栏组件(CommonTitleBar)、药物输入区、添加按钮区以及药物清单列表区。
在ArkUI框架中,每一个页面都是一个独立的@Component装饰器组件。MedicineReminder组件作为整个应用的根组件,负责管理所有的状态变量和业务逻辑,包括药物清单、药物名称输入、提醒时间输入等。UI渲染通过build()方法中的声明式代码完成,所有UI更新都由状态变量变化自动触发。
┌─────────────────────────────────────────────────────────┐
│ MedicineReminder页面 │
│ ┌─────────────────────────────────────────────────┐ │
│ │ CommonTitleBar组件 │ │
│ │ (导航栏+标题显示) │ │
│ └─────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 药物输入区 │ │
│ │ (药物名称 + 提醒时间) │ │
│ └─────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 添加按钮区 │ │
│ │ (添加提醒按钮) │ │
│ └─────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 药物清单列表区 │ │
│ │ (药物+时间+状态+操作) │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
2.2 模块依赖关系
从依赖关系的角度分析,药物提醒应用主要依赖以下几个核心模块:
首先是CommonTitleBar组件,该组件提供了统一的页面标题栏和返回按钮功能。作为项目中的通用组件,CommonTitleBar被多个页面复用,确保了应用内导航体验的一致性。
TextInput组件是ArkUI框架提供的文本输入控件,用于接收用户的药物名称和提醒时间输入。应用使用两个TextInput分别输入药物名称和时间。
List组件是ArkUI框架提供的列表渲染控件,用于展示药物清单列表。通过ForEach循环渲染每个药物项。
Button组件是ArkUI框架提供的按钮控件,用于触发添加药物和标记服用等操作。
2.3 数据模型设计
药物提醒应用的数据模型包含以下核心状态变量:
@State app_medicines: Record<string, string>[] = []; // 药物清单列表
@State app_medicineName: string = ''; // 药物名称输入值
@State app_reminderTime: string = ''; // 提醒时间输入值
| 状态变量 | 类型 | 初始值 | 说明 |
|---|---|---|---|
| app_medicines | Record[] | [] | 药物清单数组,每条记录包含名称、时间、状态 |
| app_medicineName | string | ‘’ | 用户输入的药物名称 |
| app_reminderTime | string | ‘’ | 用户输入的提醒时间 |
记录项的数据结构:
interface MedicineReminder {
name: string; // 药物名称
time: string; // 提醒时间
status: string; // 服用状态(待服用/已服用)
}
药物状态的取值范围:
| 状态 | 说明 |
|---|---|
| 待服用 | 尚未服用,需要在提醒时间服药 |
| 已服用 | 已经服药完成 |
3. 核心代码详解
3.1 状态管理机制
药物提醒应用的状态管理遵循ArkTS框架的核心设计理念,使用@State装饰器声明响应式状态变量。
@State app_medicines: Record<string, string>[] = [];
@State app_medicineName: string = '';
@State app_reminderTime: string = '';
ArkTS作为静态类型语言,要求所有变量必须显式声明类型。这里的类型声明(Record[]、string)都是不可或缺的。
状态变量的职责划分:
app_medicines:存储药物提醒清单,是应用的核心数据。用户添加的每条提醒都会push到这个数组中,List组件会自动渲染这个数组的所有元素。
app_medicineName:存储用户输入的药物名称。这是临时状态,每次输入变化时都会更新。
app_reminderTime:存储用户输入的提醒时间。这也是临时状态。
3.2 药物输入区设计
药物提醒使用两个TextInput组件分别接收药物名称和时间输入:
Column({ space: 16 }) {
TextInput({ placeholder: '药物名称' })
.width('100%')
.onChange((app_value: string) => {
this.app_medicineName = app_value;
})
TextInput({ placeholder: '提醒时间(如 08:00)' })
.width('100%')
.onChange((app_value: string) => {
this.app_reminderTime = app_value;
})
}
TextInput组件的关键配置:
placeholder属性:设置输入框的占位提示文字,告诉用户应该输入什么内容
时间格式提示:第二个输入框的placeholder包含时间格式示例"如 08:00"
onChange事件:每次输入变化时触发回调,更新对应的状态变量
width(‘100%’):输入框宽度占满容器
3.3 提醒添加逻辑实现
药物提醒的添加逻辑是应用的核心业务功能:
Button('添加提醒')
.width('100%')
.onClick(() => {
let app_medicine: Record<string, string> = {
'name': this.app_medicineName,
'time': this.app_reminderTime,
'status': '待服用'
};
this.app_medicines.push(app_medicine);
})
添加提醒的业务流程:
1. 创建药物对象:构建一个包含名称、时间和状态的药物对象
2. 获取输入值:从状态变量中获取用户输入的药物名称和时间
3. 设置初始状态:新添加的提醒状态默认为"待服用"
4. 添加到清单:使用数组的push方法将药物对象添加到清单末尾
3.4 药物清单列表设计
药物清单列表使用List组件渲染:
List() {
ForEach(this.app_medicines, (app_medicine: Record<string, string>, app_index: number) => {
ListItem() {
Row() {
Column({ space: 4 }) {
Text(app_medicine['name'])
.fontSize(16)
.fontWeight(FontWeight.Medium)
.fontColor($r('app.color.app_color_text_primary'))
Text(`提醒时间: ${app_medicine['time']}`)
.fontSize(12)
.fontColor($r('app.color.app_color_text_tertiary'))
}
Blank()
Row({ space: 8 }) {
Text(app_medicine['status'])
.fontSize(14)
.fontColor($r('app.color.app_color_warning'))
Button('服用')
.fontSize(12)
.onClick(() => {
this.app_medicines[app_index]['status'] = '已服用';
})
}
}
.width('100%')
.padding(12)
.backgroundColor($r('app.color.app_color_white'))
.borderRadius(8)
}
})
}
.width('100%')
.layoutWeight(1)
List组件的关键点:
ForEach循环:遍历app_medicines数组,为每个元素渲染一个ListItem
索引参数:ForEach的第二个参数是索引,用于在点击时定位具体项
记录卡片样式:白色背景、8vp圆角、12vp内边距
药物信息:左侧显示药物名称和提醒时间
状态和操作:右侧显示服药状态标签和"服用"按钮
服用操作:点击按钮后更新对应索引项的状态为"已服用"
3.5 服用状态更新
服用状态更新通过索引定位实现:
Button('服用')
.fontSize(12)
.onClick(() => {
this.app_medicines[app_index]['status'] = '已服用';
})
状态更新的实现要点:
索引定位:通过ForEach提供的app_index参数精确定位要更新的项
直接修改:ArkTS支持对数组元素的对象属性进行直接修改
响应式更新:状态修改后,UI会自动重新渲染该列表项
4. UI布局设计
4.1 整体布局结构
药物提醒的UI布局采用垂直堆叠的Column容器组织各个功能区块:
build() {
Column() {
CommonTitleBar({
app_title: '药物提醒',
app_showBack: true
})
Column({ space: 16 }) {
// 药物名称输入
TextInput({ placeholder: '药物名称' })
.width('100%')
.onChange(...)
// 提醒时间输入
TextInput({ placeholder: '提醒时间(如 08:00)' })
.width('100%')
.onChange(...)
// 添加按钮
Button('添加提醒')
.width('100%')
.onClick(...)
// 药物清单列表
List() {...}
.width('100%')
.layoutWeight(1)
}
.width('100%')
.padding(16)
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.app_color_background'))
}
布局设计采用"输入 -> 添加 -> 列表"的信息流顺序,符合用户的操作习惯。
4.2 输入区域设计
输入区域包含两个上下排列的输入框:
TextInput({ placeholder: '药物名称' })
.width('100%')
.onChange((app_value: string) => {
this.app_medicineName = app_value;
})
TextInput({ placeholder: '提醒时间(如 08:00)' })
.width('100%')
.onChange((app_value: string) => {
this.app_reminderTime = app_value;
})
设计要点:
Column布局:两个输入框垂直排列
space: 16:控制两个输入框之间的间距
placeholder提示:提供清晰的输入提示,包括格式示例
宽度设置:width(‘100%’)使输入框占满容器宽度
4.3 药物卡片设计
药物卡片采用左右分栏加按钮的布局:
Row() {
// 左侧:药物信息
Column({ space: 4 }) {
Text(app_medicine['name'])
.fontSize(16)
.fontWeight(FontWeight.Medium)
.fontColor($r('app.color.app_color_text_primary'))
Text(`提醒时间: ${app_medicine['time']}`)
.fontSize(12)
.fontColor($r('app.color.app_color_text_tertiary'))
}
// 中间:空白填充
Blank()
// 右侧:状态和按钮
Row({ space: 8 }) {
Text(app_medicine['status'])
.fontSize(14)
.fontColor($r('app.color.app_color_warning'))
Button('服用')
.fontSize(12)
.onClick(() => {
this.app_medicines[app_index]['status'] = '已服用';
})
}
}
设计要点:
Row布局:采用左中右三栏布局
Blank组件:占据中间空间,将右侧内容推到最右边
Column嵌套:左侧的药物名称和时间上下排列
字体层级:药物名称16vp Bold、时间12vp灰色,形成清晰层次
按钮组:状态标签和服用按钮水平排列
5. 提醒机制设计
5.1 时间格式规范
提醒时间采用24小时制,格式为"HH:mm":
| 格式示例 | 说明 |
|---|---|
| 08:00 | 上午8点 |
| 12:30 | 中午12点30分 |
| 19:45 | 晚上7点45分 |
| 22:00 | 晚上10点 |
5.2 提醒状态流转
药物提醒的状态流转设计:
[待服用] --点击"服用"--> [已服用]
状态设计说明:
待服用:表示尚未服药,需要在提醒时间服药
已服用:表示已经完成服药
5.3 时间验证
对提醒时间输入进行格式验证:
private app_validateTime(app_time: string): boolean {
// 验证格式:HH:mm
let app_pattern: RegExp = /^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/;
return app_pattern.test(app_time);
}
时间验证规则:
| 检查项 | 规则 |
|---|---|
| 小时 | 0-23 |
| 分钟 | 00-59 |
| 分隔符 | 冒号(😃 |
6. 数据持久化
6.1 AppStorage存储机制
药物提醒应用应该使用AppStorage实现数据的持久化存储:
// 保存药物清单
app_saveMedicines(): void {
app_setString('medicine_reminders', JSON.stringify(this.app_medicines));
}
// 加载药物清单
app_loadMedicines(): void {
const app_medicinesStr: string = app_getString('medicine_reminders', '[]');
try {
this.app_medicines = JSON.parse(app_medicinesStr);
} catch (error) {
this.app_medicines = [];
}
}
数据持久化的执行时机:
| 生命周期 | 执行操作 |
|---|---|
| aboutToAppear | app_loadMedicines() |
| aboutToDisappear | app_saveMedicines() |
| 添加提醒后 | app_saveMedicines() |
| 服用操作后 | app_saveMedicines() |
6.2 JSON序列化存储
药物清单数组可以直接序列化为JSON字符串进行存储:
// 保存
const app_jsonStr: string = JSON.stringify(this.app_medicines);
app_setString('medicine_reminders', app_jsonStr);
// 加载
const app_jsonStr: string = app_getString('medicine_reminders', '[]');
this.app_medicines = JSON.parse(app_jsonStr);
7. 扩展与展望
7.1 当前功能总结
药物提醒应用实现了以下核心功能:
| 功能模块 | 实现描述 |
|---|---|
| 药物添加 | 输入药物名称和提醒时间添加到清单 |
| 提醒展示 | 用List组件展示所有药物提醒 |
| 状态显示 | 显示每条提醒的服药状态 |
| 服用记录 | 点击"服用"按钮标记为已服用 |
7.2 功能扩展方向
基于当前的药物提醒应用架构,可以进行以下功能扩展:
定时提醒通知:利用HarmonyOS的后台任务和通知机制,在设定时间发送提醒通知。
import notification from '@ohos.notificationManager';
import workScheduler from '@ohos.workScheduler';
// 创建定时工作
workScheduler.scheduleWork({
workId: 1,
flexTime: 3600000, // 提前1小时
timer: {
type: workScheduler.TimerType.EXACTLY,
triggerAt: this.app_getTimestamp(this.app_reminderTime)
}
});
重复提醒:支持设置每日重复、每周重复等提醒频率。
interface MedicineReminder {
name: string;
time: string;
status: string;
repeatType: 'daily' | 'weekly' | 'monthly';
daysOfWeek?: number[]; // 0-6 for weekly
}
剂量记录:记录每次服用的药量。
interface MedicineReminder {
name: string;
time: string;
status: string;
dosage: string; // e.g., "2片"
}
药物分类:对药物进行分类管理,如降压药、降糖药等。
interface MedicineReminder {
name: string;
time: string;
status: string;
category: string; // 高血压 / 糖尿病 / 感冒药 等
}
服药历史:记录每次服药的实际时间。
interface MedicineRecord {
name: string;
scheduledTime: string;
actualTime: string;
date: string;
}
库存管理:跟踪药物剩余数量,提醒补充。
interface MedicineReminder {
name: string;
time: string;
status: string;
remainingCount: number;
refillReminder: number; // 低于此数量时提醒
}
相互作用提醒:当同时服用多种药物时,提供可能的相互作用警告。
private app_checkInteractions(): string[] {
let app_warnings: string[] = [];
// 检查药物相互作用
return app_warnings;
}
8. HarmonyOS后台任务开发
8.1 定时任务概述
HarmonyOS提供了@kit.WorkSchedulerKit用于调度后台任务。在药物提醒场景中,可以使用定时任务在设定时间发送通知。
定时任务的基本结构:
import workScheduler from '@ohos.workScheduler';
workScheduler.scheduleWork({
workId: 1,
flexTime: 3600000, // 宽限时间(毫秒)
timer: {
type: workScheduler.TimerType.EXACTLY,
triggerAt: triggerTimestamp
},
work: {
appStorageUri: 'MedicineReminder',
abilityName: 'EntryAbility'
}
});
8.2 通知发布
结合定时任务发送服药提醒通知:
import notification from '@ohos.notificationManager';
// 发送服药提醒
notification.publish({
id: 1005,
content: {
title: '服药提醒',
text: `该服用${this.app_medicineName}了`
}
});
8.3 权限配置
使用后台任务和通知需要在module.json5中配置权限:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.NOTIFICATION_CONTROLLER",
"reason": "$string:notification_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "always"
}
},
{
"name": "ohos.permission.WORK_SCHEDULER",
"reason": "$string:work_scheduler_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "always"
}
}
]
}
}
9. 健康管理类应用设计要点
9.1 服药依从性
药物提醒的核心目标是提高服药依从性:
简单操作:服用操作应该一键完成,减少用户负担
清晰状态:让用户一眼看出哪些药已服用、哪些待服用
及时提醒:在正确的时间发送提醒,避免漏服
9.2 数据准确性
健康管理类应用的数据准确性至关重要:
输入验证:对药物名称和提醒时间进行格式验证
private app_validateInput(app_name: string, app_time: string): boolean {
if (app_name.length === 0) {
return false; // 药物名称不能为空
}
let app_pattern: RegExp = /^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/;
if (!app_pattern.test(app_time)) {
return false; // 时间格式不正确
}
return true;
}
状态同步:确保服用状态更新后UI和存储都正确更新
9.3 用户体验
健康管理类应用的用户体验需要特别关注:
操作简便:减少输入步骤,支持快速添加和记录
视觉清晰:状态变化应该显而易见
温和提醒:提醒文案应该温和友善,避免造成焦虑
10. 技术要点总结
10.1 ArkTS核心特性使用
通过药物提醒应用,我们可以总结以下ArkTS核心特性的使用方法:
@State装饰器:用于声明组件级别的响应式状态
@State app_medicines: Record<string, string>[] = [];
@State app_medicineName: string = '';
@State app_reminderTime: string = '';
TextInput组件:用于接收用户文本输入
TextInput({ placeholder: '药物名称' })
.width('100%')
.onChange((app_value: string) => {
this.app_medicineName = app_value;
})
List + ForEach + 索引:用于渲染带索引的列表数据
List() {
ForEach(this.app_medicines, (app_medicine: Record<string, string>, app_index: number) => {
ListItem() {
Button('服用')
.onClick(() => {
this.app_medicines[app_index]['status'] = '已服用';
})
}
})
}
10.2 列表项索引使用
ForEach提供了索引参数用于精确定位列表项:
ForEach(this.app_medicines, (app_medicine: Record<string, string>, app_index: number) => {
// app_index 是当前项的索引
// 用于在点击时更新对应的项
Button('服用')
.onClick(() => {
this.app_medicines[app_index]['status'] = '已服用';
})
})
10.3 状态更新机制
ArkTS支持对数组元素的对象属性进行直接修改:
this.app_medicines[app_index]['status'] = '已服用';
修改后,框架会自动触发UI重新渲染该列表项。
10.4 健康管理类应用架构建议
健康管理类应用的技术架构建议:
数据模型设计:使用接口定义清晰的数据结构
interface MedicineReminder {
name: string;
time: string;
status: string;
}
输入验证:在添加提醒前验证输入数据的合理性
private app_validateInput(name: string, time: string): boolean {
// 验证逻辑
}
持久化存储:使用AppStorage存储药物清单数据
app_setString('medicine_reminders', JSON.stringify(this.app_medicines));
提醒机制:使用WorkSchedulerKit实现定时提醒
workScheduler.scheduleWork({
workId: 1,
timer: {...}
});
希望本文对药物提醒应用的技术剖析能够帮助开发者深入理解HarmonyOS ArkTS的开发范式和核心API使用技巧,特别是List索引使用、TextInput输入处理、状态更新机制、定时提醒实现以及健康管理类应用的设计要点等关键技术点。
更多推荐




所有评论(0)