在这里插入图片描述

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输入处理、状态更新机制、定时提醒实现以及健康管理类应用的设计要点等关键技术点。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐