鸿蒙血压记录 - 健康范围判断 健康记录应用-ArkTS完成

1. 应用概述
血压记录(BloodPressure)是一款基于HarmonyOS ArkTS框架开发的健康数据记录工具,其核心功能是帮助用户记录每日血压数值、追踪血压变化趋势、评估血压健康状态。这款应用将传统的血压记录方式数字化,提供直观的数值输入、历史记录展示和智能状态评估功能,为用户的血压健康管理提供数据支持。
在技术实现层面,血压记录应用充分展示了HarmonyOS声明式UI开发范式的核心能力。通过@State装饰器实现响应式状态管理,TextInput组件实现血压数值输入,List组件实现历史记录列表渲染,状态判断算法实现血压分类评估,以及清晰的列表卡片UI设计,构成了一个功能聚焦的血压健康助手应用。应用的代码结构简洁清晰,使用HarmonyOS原生API完成所有功能实现,没有引入任何复杂的第三方依赖。
本技术博客将从应用架构设计、核心代码实现、血压评估算法、数据模型设计、状态管理机制、List组件使用以及健康类应用设计要点等多个维度,对这款血压记录应用进行全面的技术剖析。通过本文的深入讲解,读者不仅能够理解如何实现一个功能完善的血压记录应用,更能够掌握HarmonyOS ArkTS开发中的核心知识点,特别是TextInput输入处理、List列表渲染、状态判断逻辑、健康数据评估以及健康类应用的设计要点等关键技术点。
2. 技术架构分析
2.1 整体架构设计
血压记录应用采用了单页面架构(Single Page Application),整个应用仅包含一个主页面,通过组件化设计将UI展示与业务逻辑进行有效分离。从代码组织角度来看,应用主要分为以下几个核心部分:页面入口组件(BloodPressure)、通用标题栏组件(CommonTitleBar)、数值输入区、添加按钮区以及历史记录列表区。
在ArkUI框架中,每一个页面都是一个独立的@Component装饰器组件。BloodPressure组件作为整个应用的根组件,负责管理所有的状态变量和业务逻辑,包括收缩压输入值、舒张压输入值、血压记录列表、状态评估结果等。UI渲染通过build()方法中的声明式代码完成,所有UI更新都由状态变量变化自动触发。
┌─────────────────────────────────────────────────────────┐
│ BloodPressure页面 │
│ ┌─────────────────────────────────────────────────┐ │
│ │ CommonTitleBar组件 │ │
│ │ (导航栏+标题显示) │ │
│ └─────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 数值输入区 │ │
│ │ (收缩压 + 舒张压输入框) │ │
│ └─────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 添加按钮区 │ │
│ │ (添加记录按钮) │ │
│ └─────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 历史记录列表区 │ │
│ │ (日期+数值+状态) │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
2.2 模块依赖关系
从依赖关系的角度分析,血压记录应用主要依赖以下几个核心模块:
首先是CommonTitleBar组件,该组件提供了统一的页面标题栏和返回按钮功能。作为项目中的通用组件,CommonTitleBar被多个页面复用,确保了应用内导航体验的一致性。
TextInput组件是ArkUI框架提供的文本输入控件,用于接收用户的血压数值输入。应用使用两个TextInput分别输入收缩压和舒张压数值。
List组件是ArkUI框架提供的列表渲染控件,用于展示历史血压记录列表。通过ForEach循环渲染每个记录项。
Button组件是ArkUI框架提供的按钮控件,用于触发添加记录操作。
2.3 数据模型设计
血压记录应用的数据模型包含以下核心状态变量:
@State app_records: Record<string, string>[] = []; // 血压记录列表
@State app_systolic: string = ''; // 收缩压输入值
@State app_diastolic: string = ''; // 舒张压输入值
| 状态变量 | 类型 | 初始值 | 说明 |
|---|---|---|---|
| app_records | Record[] | [] | 血压记录数组,每条记录包含日期、收缩压、舒张压、状态 |
| app_systolic | string | ‘’ | 用户输入的收缩压数值 |
| app_diastolic | string | ‘’ | 用户输入的舒张压数值 |
记录项的数据结构:
interface BloodPressureRecord {
date: string; // 记录日期
systolic: string; // 收缩压数值(mmHg)
diastolic: string; // 舒张压数值(mmHg)
status: string; // 血压状态评估结果
}
血压状态的取值范围:
| 状态 | 收缩压条件 | 舒张压条件 | 医学含义 |
|---|---|---|---|
| 正常 | < 120 mmHg | < 80 mmHg | 血压在健康范围内 |
| 偏高 | 120-139 mmHg | 80-89 mmHg | 处于高血压前期 |
| 高血压 | >= 140 mmHg | >= 90 mmHg | 确诊高血压 |
3. 核心代码详解
3.1 状态管理机制
血压记录应用的状态管理遵循ArkTS框架的核心设计理念,使用@State装饰器声明响应式状态变量。
@State app_records: Record<string, string>[] = [];
@State app_systolic: string = '';
@State app_diastolic: string = '';
ArkTS作为静态类型语言,要求所有变量必须显式声明类型。这里的类型声明(Record[]、string)都是不可或缺的。
状态变量的职责划分:
app_records:存储血压记录列表,是应用的核心数据。用户添加的每条记录都会push到这个数组中,List组件会自动渲染这个数组的所有元素。
app_systolic:存储用户输入的收缩压数值。这是一个临时状态,每次输入变化时都会更新,当用户提交记录后会清空。
app_diastolic:存储用户输入的舒张压数值。与收缩压类似,也是临时状态。
3.2 数值输入处理
血压记录使用TextInput组件接收用户输入:
Row({ space: 12 }) {
Column() {
Text('收缩压')
.fontSize(12)
.fontColor($r('app.color.app_color_text_tertiary'))
TextInput({ placeholder: 'mmHg' })
.width('100%')
.onChange((app_value: string) => {
this.app_systolic = app_value;
})
}
.layoutWeight(1)
Column() {
Text('舒张压')
.fontSize(12)
.fontColor($r('app.color.app_color_text_tertiary'))
TextInput({ placeholder: 'mmHg' })
.width('100%')
.onChange((app_value: string) => {
this.app_diastolic = app_value;
})
}
.layoutWeight(1)
}
TextInput组件的关键配置:
placeholder属性:设置输入框的占位提示文字"mmHg",告诉用户应该输入什么单位
onChange事件:每次输入变化时触发回调,更新对应的状态变量
layoutWeight属性:设置为1使两个输入框等宽分布
width(‘100%’):输入框宽度占满容器
3.3 记录添加逻辑实现
血压记录的添加逻辑是应用的核心业务功能:
Button('添加记录')
.width('100%')
.onClick(() => {
let app_record: Record<string, string> = {
'date': new Date().toLocaleDateString(),
'systolic': this.app_systolic,
'diastolic': this.app_diastolic,
'status': this.app_getStatus()
};
this.app_records.push(app_record);
})
添加记录的业务流程:
1. 创建记录对象:构建一个包含日期、数值和状态的记录对象
2. 获取当前日期:使用new Date().toLocaleDateString()获取当前日期的本地化字符串表示
3. 血压状态评估:调用app_getStatus()方法根据输入数值计算血压状态
4. 添加到列表:使用数组的push方法将记录添加到列表末尾
5. 自动清空输入:输入框的值状态不会自动清空(当前实现),需要在后续优化中改进
3.4 血压状态评估算法
血压状态评估是应用的核心算法,根据医学标准进行判断:
private app_getStatus(): string {
let app_sys: number = parseInt(this.app_systolic || '0');
let app_dia: number = parseInt(this.app_diastolic || '0');
if (app_sys < 120 && app_dia < 80) {
return '正常';
} else if (app_sys < 140 && app_dia < 90) {
return '偏高';
} else {
return '高血压';
}
}
血压评估算法解析:
参数获取:从状态变量中获取收缩压和舒张压数值,使用parseInt转换为数字类型
空值处理:使用|| '0'处理空字符串情况,确保parseInt不会返回NaN
判断逻辑:按照中国高血压防治指南的标准进行三级分类
血压分级标准(依据《中国高血压防治指南2018年修订版》):
| 分类 | 收缩压(mmHg) | 舒张压(mmHg) |
|---|---|---|
| 正常血压 | < 120 | 且 < 80 |
| 正常高值 | 120-139 | 或 80-89 |
| 高血压 | >= 140 | 或 >= 90 |
3.5 状态颜色映射
为了直观展示血压状态,应用使用不同颜色标识不同状态:
private app_getStatusColor(app_status: string): Resource {
if (app_status === '正常') {
return $r('app.color.app_color_success');
} else if (app_status === '偏高') {
return $r('app.color.app_color_warning');
} else {
return $r('app.color.app_color_danger');
}
}
状态颜色映射规则:
| 状态 | 颜色 | 含义 |
|---|---|---|
| 正常 | success(绿色) | 血压在健康范围内 |
| 偏高 | warning(黄色) | 处于高血压前期,需要关注 |
| 高血压 | danger(红色) | 血压偏高,需要就医或调整生活习惯 |
4. UI布局设计
4.1 整体布局结构
血压记录的UI布局采用垂直堆叠的Column容器组织各个功能区块:
build() {
Column() {
CommonTitleBar({
app_title: '血压记录',
app_showBack: true
})
Column({ space: 16 }) {
// 输入区域
Row({ space: 12 }) {
Column() {...} // 收缩压输入
Column() {...} // 舒张压输入
}
// 添加按钮
Button('添加记录')
.width('100%')
.onClick(...)
// 历史记录列表
List() {
ForEach(this.app_records, (app_record: Record<string, string>) => {
ListItem() {...}
})
}
.width('100%')
.layoutWeight(1)
}
.width('100%')
.padding(16)
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.app_color_background'))
}
布局设计采用"输入 -> 添加 -> 列表"的信息流顺序,符合用户的操作习惯。
4.2 输入区域设计
输入区域包含两个并列的血压输入框:
Row({ space: 12 }) {
Column() {
Text('收缩压')
.fontSize(12)
.fontColor($r('app.color.app_color_text_tertiary'))
TextInput({ placeholder: 'mmHg' })
.width('100%')
.onChange((app_value: string) => {
this.app_systolic = app_value;
})
}
.layoutWeight(1)
Column() {
Text('舒张压')
.fontSize(12)
.fontColor($r('app.color.app_color_text_tertiary'))
TextInput({ placeholder: 'mmHg' })
.width('100%')
.onChange((app_value: string) => {
this.app_diastolic = app_value;
})
}
.layoutWeight(1)
}
设计要点:
Row布局:两个输入框水平并排,使用layoutWeight(1)使它们等宽分布
标签文字:使用小字号(12vp)和灰色文字标注输入项含义
占位提示:placeholder设置为"mmHg",明确数值的单位
间距控制:Row的space: 12控制两个输入框之间的间距
4.3 历史记录列表设计
历史记录列表使用List组件渲染:
List() {
ForEach(this.app_records, (app_record: Record<string, string>) => {
ListItem() {
Row() {
Column({ space: 4 }) {
Text(app_record['date'])
.fontSize(12)
.fontColor($r('app.color.app_color_text_tertiary'))
Text(`${app_record['systolic']}/${app_record['diastolic']} mmHg`)
.fontSize(18)
.fontWeight(FontWeight.Medium)
.fontColor($r('app.color.app_color_text_primary'))
}
Blank()
Text(app_record['status'])
.fontSize(14)
.fontColor(this.app_getStatusColor(app_record['status']))
}
.width('100%')
.padding(12)
.backgroundColor($r('app.color.app_color_white'))
.borderRadius(8)
}
})
}
.width('100%')
.layoutWeight(1)
List组件的关键点:
ForEach循环:遍历app_records数组,为每个元素渲染一个ListItem
记录卡片样式:白色背景、8vp圆角、12vp内边距
日期和数值:日期在上方(灰色小字),数值在下方(深色大字)
状态标签:使用不同颜色展示血压状态(绿色/黄色/红色)
Blank组件:将状态标签推到右侧,实现右对齐
5. List组件深入理解
5.1 List组件概述
List组件是ArkUI框架提供的列表渲染组件,用于展示可滚动的数据列表。它是健康类应用展示历史记录的核心组件。
List组件的基本结构:
List() {
ForEach(items, (item: Type) => {
ListItem() {
// 单项内容
}
})
}
5.2 ForEach循环渲染
ForEach是ArkUI框架提供的循环渲染指令:
ForEach(
arr: Array<T>, // 要遍历的数组
itemGenerator: (item: T, index: number) => void, // 生成函数
keyGenerator?: (item: T, index: number) => string // 可选的键生成函数
)
ForEach的工作原理:
数据驱动:ForEach会根据数组内容自动渲染UI,数组变化时自动更新列表
键值追踪:通过keyGenerator生成唯一键,追踪每个列表项的身份
性能优化:框架会根据键值判断哪些列表项需要重新渲染
5.3 列表项样式设计
列表项是列表中的单个元素,通常呈现为一个卡片:
ListItem() {
Row() {
// 左侧:日期和数值
Column({ space: 4 }) {...}
// 右侧:状态标签
Blank()
Text(app_record['status'])
}
.width('100%')
.padding(12)
.backgroundColor($r('app.color.app_color_white'))
.borderRadius(8)
}
列表项样式要点:
背景色:使用白色背景与页面背景区分
圆角:8vp的圆角提供柔和的视觉感受
内边距:12vp的内边距确保内容不贴近边缘
宽度:width(‘100%’)使列表项占满列表宽度
6. 血压健康知识
6.1 血压基本概念
血压是血液在血管内流动时对血管壁产生的压力。心室收缩时,血液从心室泵入动脉,此时动脉血压的最高值称为收缩压(俗称"高压")。心室舒张时,动脉血压降至最低,称为舒张压(俗称"低压")。
血压表示方法:
// 标准表示:收缩压/舒张压 mmHg
"120/80 mmHg"
// 收缩压120,舒张压80
6.2 正常血压范围
根据《中国高血压防治指南2018年修订版》:
| 分类 | 收缩压(mmHg) | 舒张压(mmHg) |
|---|---|---|
| 正常血压 | < 120 | 且 < 80 |
| 正常高值 | 120-139 | 或 80-89 |
| 高血压 | >= 140 | 或 >= 90 |
6.3 血压测量注意事项
正确的血压测量对于获得准确数据至关重要:
测量前准备:测量前30分钟避免剧烈运动、进食、饮酒或吸烟
测量姿势:坐着测量时,背部有支撑,手臂放在心脏水平高度
测量环境:保持安静,避免说话
测量频率:建议早晚各测量一次,取平均值记录
7. 数据持久化
7.1 AppStorage存储机制
血压记录应用应该使用AppStorage实现数据的持久化存储。在HarmonyOS中,AppStorage是应用级的状态存储服务,提供了键值对形式的轻量级数据存储能力。
// 保存血压记录
app_saveRecords(): void {
app_setString('bp_records', JSON.stringify(this.app_records));
}
// 加载血压记录
app_loadRecords(): void {
const app_recordsStr: string = app_getString('bp_records', '[]');
try {
this.app_records = JSON.parse(app_recordsStr);
} catch (error) {
this.app_records = [];
}
}
数据持久化的执行时机:
| 生命周期 | 执行操作 |
|---|---|
| aboutToAppear | app_loadRecords() |
| aboutToDisappear | app_saveRecords() |
| 添加记录后 | app_saveRecords() |
7.2 JSON序列化存储
血压记录数组可以直接序列化为JSON字符串进行存储:
// 保存
const app_jsonStr: string = JSON.stringify(this.app_records);
app_setString('bp_records', app_jsonStr);
// 加载
const app_jsonStr: string = app_getString('bp_records', '[]');
this.app_records = JSON.parse(app_jsonStr);
JSON格式存储的优点是可以完整保存记录数组的结构,包括日期、数值和状态所有字段。
8. 扩展与展望
8.1 当前功能总结
血压记录应用实现了以下核心功能:
| 功能模块 | 实现描述 |
|---|---|
| 血压输入 | 两个输入框分别输入收缩压和舒张压 |
| 状态评估 | 根据医学标准判断血压状态(正常/偏高/高血压) |
| 记录添加 | 将血压数据和时间戳添加到记录列表 |
| 记录展示 | 用List组件展示历史血压记录 |
| 状态颜色 | 用颜色区分不同血压状态 |
8.2 功能扩展方向
基于当前的血压记录应用架构,可以进行以下功能扩展:
图表展示:添加血压趋势图表,直观展示血压变化趋势。
// 使用chart组件绘制趋势图
Chart()
.type(ChartType.Line)
.dataSet(this.app_bpHistory)
数据导出:支持将血压记录导出为CSV或PDF格式。
// 导出为CSV
let app_csv: string = '日期,收缩压,舒张压,状态\n';
for (let i = 0; i < this.app_records.length; i++) {
const app_r: Record<string, string> = this.app_records[i];
app_csv += `${app_r['date']},${app_r['systolic']},${app_r['diastolic']},${app_r['status']}\n`;
}
提醒功能:在固定时间提醒用户测量血压。
// 使用通知提醒
notification.publish({
id: 1002,
content: {
title: '血压提醒',
text: '该测量血压了'
}
});
血压分类细化:将高血压进一步分为1级、2级、3级。
private app_getDetailedStatus(): string {
let app_sys: number = parseInt(this.app_systolic || '0');
let app_dia: number = parseInt(this.app_diastolic || '0');
if (app_sys >= 180 || app_dia >= 110) {
return '3级高血压(重度)';
} else if (app_sys >= 160 || app_dia >= 100) {
return '2级高血压(中度)';
} else if (app_sys >= 140 || app_dia >= 90) {
return '1级高血压(轻度)';
}
// ...
}
平均值计算:计算一段时间内的平均血压值。
private app_getAverage(): { sys: number; dia: number } {
if (this.app_records.length === 0) {
return { sys: 0, dia: 0 };
}
let app_totalSys: number = 0;
let app_totalDia: number = 0;
for (let i = 0; i < this.app_records.length; i++) {
app_totalSys += parseInt(this.app_records[i]['systolic'] || '0');
app_totalDia += parseInt(this.app_records[i]['diastolic'] || '0');
}
return {
sys: Math.round(app_totalSys / this.app_records.length),
dia: Math.round(app_totalDia / this.app_records.length)
};
}
数据同步:支持将数据同步到云端,实现多设备访问。
9. 健康类应用设计要点
9.1 数据准确性
健康类应用的数据准确性直接影响用户的健康决策:
输入验证:对用户输入的数值进行合理性校验,如血压范围应在30-250 mmHg之间
private app_validateInput(app_sys: string, app_dia: string): boolean {
let app_sysNum: number = parseInt(app_sys);
let app_diaNum: number = parseInt(app_dia);
if (isNaN(app_sysNum) || isNaN(app_diaNum)) {
return false; // 非数字
}
if (app_sysNum < 30 || app_sysNum > 250) {
return false; // 超出合理范围
}
if (app_diaNum < 30 || app_diaNum > 150) {
return false; // 超出合理范围
}
if (app_sysNum <= app_diaNum) {
return false; // 收缩压应该大于舒张压
}
return true;
}
明确数据来源:记录应该基于用户手动输入或校准后的设备读数
合理默认值:不提供可能误导用户的默认值
9.2 医学参考
健康类应用的健康评估应该基于权威医学指南:
引用国家标准:本应用参照《中国高血压防治指南》进行血压分级
清晰告知用户:评估结果仅供参考,不能替代专业医疗诊断
建议就医场景:当血压处于高血压范围时,明确建议用户咨询医生
9.3 隐私保护
健康数据属于敏感个人信息:
本地存储优先:数据存储在设备本地,不上传到服务器
用户控制权:用户可以查看、导出和删除自己的数据
最小化收集:只收集功能必需的数据
10. 技术要点总结
10.1 ArkTS核心特性使用
通过血压记录应用,我们可以总结以下ArkTS核心特性的使用方法:
@State装饰器:用于声明组件级别的响应式状态
@State app_records: Record<string, string>[] = [];
@State app_systolic: string = '';
@State app_diastolic: string = '';
TextInput组件:用于接收用户文本输入
TextInput({ placeholder: 'mmHg' })
.width('100%')
.onChange((app_value: string) => {
this.app_systolic = app_value;
})
List + ForEach:用于渲染列表数据
List() {
ForEach(this.app_records, (app_record: Record<string, string>) => {
ListItem() {...}
})
}
10.2 条件判断技巧
血压评估使用多级条件判断:
if (app_sys < 120 && app_dia < 80) {
return '正常';
} else if (app_sys < 140 && app_dia < 90) {
return '偏高';
} else {
return '高血压';
}
判断顺序很重要:应该从最严格的条件开始判断,逐步放宽。
10.3 状态颜色映射
使用函数封装颜色映射逻辑,便于维护和扩展:
private app_getStatusColor(app_status: string): Resource {
if (app_status === '正常') {
return $r('app.color.app_color_success');
} else if (app_status === '偏高') {
return $r('app.color.app_color_warning');
} else {
return $r('app.color.app_color_danger');
}
}
10.4 健康类应用架构建议
健康类应用的技术架构建议:
数据模型设计:使用接口定义清晰的数据结构
interface BloodPressureRecord {
date: string;
systolic: string;
diastolic: string;
status: string;
}
输入验证:在添加记录前验证输入数据的合理性
private app_validateInput(sys: string, dia: string): boolean {
// 验证逻辑
}
持久化存储:使用AppStorage存储历史数据
app_setString('bp_records', JSON.stringify(this.app_records));
希望本文对血压记录应用的技术剖析能够帮助开发者深入理解HarmonyOS ArkTS的开发范式和核心API使用技巧,特别是TextInput输入处理、List列表渲染、条件判断逻辑、健康数据评估以及健康类应用的设计要点等关键技术点。
更多推荐



所有评论(0)