文章信息
项目英文名:SimpleHealthTracker
应用中文名称:简易健康监测器
开发环境:DevEco Studio + ArkTS(Stage 模型)
适配设备:HarmonyOS 手机设备
核心功能:BMI 指数自动计算、静息心率健康评估、表单重置、弹窗提示
解决痛点:变量关键字冲突、AlertDialog API 版本兼容编译报错全套踩坑修复
一、前言
1.1 开发背景
当下大众越来越注重日常身体健康管理,BMI 体质指数、静息心率是普通人最易自测、最基础的两项身体指标。市面上健康类 APP 功能繁杂、广告繁多,对于学生鸿蒙实训、入门开发者学习 ArkUI 语法而言,一款轻量化、无多余功能、单页面运行的健康测算工具十分适合练手。
基于此需求,本文使用 HarmonyOS ArkTS 语言开发简易健康监测器,整个项目仅依赖index.ets单页面完成全部逻辑,无需多页面跳转、无需本地数据库、无需网络请求,零基础鸿蒙开发者可直接复制代码运行。
同时,在项目编译过程中会遇到两大经典鸿蒙编译报错:
Property ‘xxx’ is not assignable to the same property in base type 自定义状态变量与系统内置属性重名冲突;
Property ‘showAlert’ does not exist on type ‘typeof AlertDialog’ 弹窗 API 版本不兼容报错。
本文会完整还原报错场景、分析报错底层原因、给出标准修复方案,不仅提供可直接运行的成品代码,还包含完整排错思路,既能作为课程实训作业,也能作为鸿蒙 ArkTS 组件开发、状态管理、弹窗交互的实战学习案例。
1.2 项目整体介绍
项目名称
工程名(创建项目填写):SimpleHealthTracker
应用展示名:简易健康监测器
技术栈:HarmonyOS ArkTS、ArkUI 声明式 UI、@State 状态管理、AlertDialog 原生弹窗、TextInput 数字输入框、Button 点击交互
核心功能清单
(1)身高、体重、静息心率数字输入框,限制仅能输入数字;
(2)自动计算 BMI 指数,公式:BMI = 体重 (kg) / 身高 (m)²;
(3)BMI 四段式健康分级:偏瘦 / 标准 / 超重 / 肥胖,不同状态显示对应彩色文字;
(4)静息心率区间判断,弹窗给出心率健康建议;
(5)输入合法性校验,空值、负数、非法数字弹出错误提示;
(6)一键重置所有输入内容与计算结果;
(7)卡片式 UI 布局,界面简洁美观,适配手机全屏展示。
学习价值
掌握 ArkTS @State响应式状态管理核心原理;
学会 TextInput 输入监听、数字类型限制、表单数据获取;
理解 Column/Row 基础布局容器、圆角卡片、间距样式开发;
掌握 Button 点击事件、业务逻辑函数封装;
吃透鸿蒙编译两大高频报错的根源与永久解决方案;
学会条件分支判断、数值运算、前端可视化结果展示。
二、开发环境搭建与项目创建
2.1 环境要求
DevEco Studio 4.0 及以上版本;
配套 HarmonyOS SDK(API 9/API 10 通用,本文代码兼容低版本 SDK);
模拟器 / 真机(HarmonyOS 3.1 及以上手机系统);
开发语言选择 ArkTS,项目模板选择「Empty Activity」空白单页面模板。
2.2 新建项目详细步骤
打开 DevEco Studio,点击「Create Project」新建工程;
模板分类选择「ArkTS」→「Empty Activity」空白页面模板;
项目参数填写(严格对应本文项目名,避免路径问题):
Project name:SimpleHealthTracker
Bundle name:自定义包名(实训可默认生成)
Save location:自定义本地存储路径,路径不要包含中文、空格;
Language:ArkTS
Device type:Phone
Compile SDK 版本:API 9 / API 10(任意均可)
点击 Finish 完成创建,等待工具自动同步依赖、构建基础工程目录;
目录定位:entry/src/main/ets/pages/Index.ets,该文件是项目唯一业务页面,删除系统自动生成的默认测试代码,替换为本文完整代码。
三、完整业务代码(可直接复制运行)
ets

@Entry
@Component
struct HealthPage {
  // 规避系统内置关键字,使用user前缀命名状态变量
  @State userHeight: string = ''
  @State userWeight: string = ''
  @State heartRate: string = ''

  // 存储计算结果与健康评级
  @State bmi: number = 0
  @State healthLevel: string = '未检测'
  @State levelColor: ResourceColor = '#666666'

  /**
   * 健康测算核心逻辑:BMI计算 + 心率评估 + 输入校验
   */
  calculateHealth() {
    // 将输入字符串转为数值类型
    const h = parseFloat(this.userHeight)
    const w = parseFloat(this.userWeight)
    const hr = parseInt(this.heartRate)

    // 输入合法性校验:身高体重必须大于0的有效数字
    if (isNaN(h) || isNaN(w) || h <= 0 || w <= 0) {
      AlertDialog.show({ message: '请输入有效的身高(m)、体重(kg)' })
      return
    }
    // 心率数值校验
    if (isNaN(hr) || hr <= 0) {
      AlertDialog.show({ message: '请输入有效心率' })
      return
    }

    // 标准BMI计算公式
    this.bmi = w / (h * h)

    // BMI区间分级判断,匹配对应健康文案与字体颜色
    if (this.bmi < 18.5) {
      this.healthLevel = '偏瘦,建议增加营养摄入'
      this.levelColor = '#0099FF'
    } else if (this.bmi >= 18.5 && this.bmi < 24) {
      this.healthLevel = '标准健康体态'
      this.levelColor = '#00CC66'
    } else if (this.bmi >= 24 && this.bmi < 28) {
      this.healthLevel = '超重,建议控制饮食多运动'
      this.levelColor = '#FF9900'
    } else {
      this.healthLevel = '肥胖,需要加强减脂锻炼'
      this.levelColor = '#FF4444'
    }

    // 静息心率区间判断逻辑
    let hrTip = ''
    if (hr < 60) hrTip = '心率偏低,若无不适无需担心'
    else if (hr > 100) hrTip = '静息心率偏高,注意休息'
    else hrTip = '静息心率正常'

    // 弹窗展示心率评估结果
    AlertDialog.show({
      title: '心率检测结果',
      message: hrTip
    })
  }

  /**
   * 重置函数:清空所有输入与计算结果
   */
  resetData() {
    this.userHeight = ''
    this.userWeight = ''
    this.heartRate = ''
    this.bmi = 0
    this.healthLevel = '未检测'
    this.levelColor = '#666666'
  }

  build() {
    Column() {
      // 页面标题
      Text('个人身体健康监测')
        .fontSize(26)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 20 })

      // 身高输入框
      TextInput({ text: this.userHeight, placeholder: '输入身高(单位:米)' })
        .width('90%')
        .height(50)
        .margin({ bottom: 12 })
        .onChange((val: string) => { this.userHeight = val })
        .type(InputType.Number)

      // 体重输入框
      TextInput({ text: this.userWeight, placeholder: '输入体重(单位:千克)' })
        .width('90%')
        .height(50)
        .margin({ bottom: 12 })
        .onChange((val: string) => { this.userWeight = val })
        .type(InputType.Number)

      // 心率输入框
      TextInput({ text: this.heartRate, placeholder: '静息心率(次/分钟)' })
        .width('90%')
        .height(50)
        .margin({ bottom: 20 })
        .onChange((val: string) => { this.heartRate = val })
        .type(InputType.Number)

      // 操作按钮行:测算按钮 + 重置按钮
      Row() {
        Button('开始健康测算', { stateEffect: true })
          .width('42%')
          .height(48)
          .fontSize(18)
          .backgroundColor('#36D399')
          .fontColor(Color.White)
          .margin({ right: 10 })
          .onClick(() => this.calculateHealth())

        Button('重置数据', { stateEffect: true })
          .width('42%')
          .height(48)
          .fontSize(18)
          .backgroundColor('#94A3B8')
          .fontColor(Color.White)
          .onClick(() => this.resetData())
      }
      .width('90%')
      .margin({ bottom: 30 })

      // 计算结果展示卡片
      Column() {
        Text(`你的BMI指数:${this.bmi.toFixed(2)}`)
          .fontSize(22)
          .margin({ bottom: 10 })

        Text(`身体状态:${this.healthLevel}`)
          .fontSize(20)
          .fontColor(this.levelColor)
      }
      .width('90%')
      .padding(20)
      .borderRadius(12)
      .backgroundColor('#F8FAFC')

    }
    .width('100%')
    .height('100%')
    .padding(16)
    .backgroundColor(Color.White)
  }
}

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

四、代码分层逻辑详细解析
4.1 @Entry、@Component 装饰器说明
@Entry:页面入口装饰器,标记当前自定义组件为应用启动首页,仅能在 Index.ets 根组件使用;
@Component:自定义组件装饰器,所有 ArkUI 页面、子组件必须添加,标识该结构体为 UI 组件;
struct HealthPage:自定义页面组件名称,统一命名规范大驼峰格式。
4.2 @State 响应式状态变量详解
@State是 ArkTS 最基础、使用频率最高的状态管理装饰器,被该装饰器修饰的变量具备响应式更新特性:变量值发生改变时,页面自动刷新对应 UI,无需手动更新视图。
本项目状态变量分为两类:
用户输入类变量
ets

@State userHeight: string = ''   // 用户身高,前缀user规避系统height关键字
@State userWeight: string = ''  // 用户体重,前缀user规避系统weight关键字
@State heartRate: string = ''   // 静息心率,无命名冲突无需前缀

重点:ArkUI 内置布局存在height()、weight()布局方法,若直接定义@State height:string会触发编译冲突报错,下文会详细拆解该报错解决方案。
计算结果存储变量
ets

@State bmi: number = 0                  // 存储计算后的BMI浮点数值
@State healthLevel: string = '未检测'   // BMI分级文字描述
@State levelColor: ResourceColor = '#666666' // 分级文字对应颜色

4.3 核心业务函数 calculateHealth ()
该函数绑定「开始健康测算」按钮点击事件,完整执行流程:
数据类型转换:TextInput 输入内容默认是字符串,使用parseFloat/parseInt转为数字,用于数学运算;
表单校验拦截:判断数值是否为 NaN、是否小于等于 0,非法输入直接弹出弹窗并终止后续逻辑;
BMI 数学运算:执行标准国际 BMI 计算公式;
多分支条件判断:四段 BMI 区间匹配,赋值对应健康文案与字体色值;
心率区间判断:根据心率数值生成健康提示文本;
AlertDialog 弹窗渲染:弹出心率评估提示框。
4.4 重置函数 resetData ()
绑定「重置数据」按钮点击事件,一次性将所有@State变量恢复初始值,实现表单清空、结果卡片还原至初始 “未检测” 状态,简化用户重复测算操作。
4.5 ArkUI 布局与组件解析
根容器Column():垂直弹性布局,页面所有元素自上而下垂直排列,宽高铺满全屏,设置全局内边距、白色背景;
TextInput数字输入框:设置type(InputType.Number)限制键盘仅弹出数字,onChange实时监听用户输入并同步赋值给状态变量;
Row()水平容器:放置两个操作按钮,均分宽度、设置左右间距;
Button按钮组件:自定义背景色、文字色、尺寸,onClick绑定业务函数,stateEffect: true开启点击按压动效;
结果卡片 Column:设置圆角borderRadius、浅灰背景、内边距,区分页面主体内容与计算结果,提升视觉层次感;
动态文字颜色:fontColor(this.levelColor)绑定状态变量,实现不同 BMI 等级文字自动变色。
五、编译报错完整还原、原因分析与解决方案(文章核心高分重点)
5.1 报错一:10505001 Property ‘height’ 类型不匹配冲突
(1)原始报错日志

plaintext
ERROR: 10505001 ArkTS Compiler Error
Error Message: Property 'height' in type 'HealthPage' is not assignable to the same property in base type 'CustomComponent'.
Type 'string' is not assignable to type '{ (value: Length): CommonAttribute; (heightValue: Length | LayoutPolicy): CommonAttribute; }'.

(2)报错触发场景
最初代码直接定义状态变量:
ets

@State height: string = ''
@State weight: string = ''

(3)底层报错原因
HarmonyOS ArkUI 底层CustomComponent基础组件内置了布局扩展方法height()、weight(),用于设置组件宽高尺寸,属于系统保留关键字。
当开发者自定义height/weight同名状态变量时,编译器无法区分你定义的字符串变量与系统内置布局方法,类型定义发生冲突,直接阻断编译,抛出 10505001 标准 ArkTS 编译错误。
(4)标准永久解决方案
给自定义输入变量增加统一业务前缀,如user、input、body,修改后无冲突:
ets

@State userHeight: string = ''
@State userWeight: string = ''

同步修改所有输入框onChange赋值、函数内取值逻辑,全局统一替换变量名,冲突彻底解决。
5.2 报错二:10505001 Property’showAlert’ 不存在
(1)原始报错日志
plaintext

ERROR: 10505001 ArkTS Compiler Error
Error Message: Property 'showAlert' does not exist on type 'typeof AlertDialog'.

(2)报错触发场景
网上部分高版本鸿蒙教程使用新 API AlertDialog.showAlert() 弹窗,低版本 SDK(API9/API10)未提供该 API,编译器识别不到方法,直接编译失败。
(3)底层报错原因
showAlert()是 HarmonyOS API11 及以上新版本新增弹窗方法,向下不兼容;API9、API10 稳定通用弹窗 API 仅有AlertDialog.show(),低版本 SDK 不存在showAlert定义。
(4)标准永久解决方案
全部弹窗代码恢复为兼容全版本 SDK 的AlertDialog.show(),删除showAlert调用,编译报错直接消失。
补充:使用 show () 会提示 API 废弃警告,警告不影响打包、模拟器运行,仅编辑器黄色提示,实训、课程作业、个人项目可忽略,无需额外处理。
5.3 报错总结避坑清单(面试 / 实训加分点)
自定义 @State 变量禁止使用 ArkUI 布局关键字:height、width、weight、margin、padding 等;
弹窗 API 优先使用AlertDialog.show()保证全 SDK 版本兼容,不盲目跟随高版本教程使用新 API;
页面路径、项目文件夹名称禁止中文、空格,避免构建工具路径解析异常;
TextInput 接收的输入值全部为 string 类型,数值运算必须手动转换parseFloat/parseInt,否则会出现字符串拼接 Bug;
表单校验不可省略,未做数字判断会出现 NaN 计算异常,界面展示错乱。
六、项目运行效果与功能测试
6.1 基础测试流程
启动模拟器 / 连接真机,点击 DevEco Studio 运行按钮,编译打包 HAP 并自动安装;
界面展示三个输入框:身高、体重、静息心率;
测试 1(非法输入):仅填写身高,点击测算,弹窗提示输入有效数值;
测试 2(偏瘦场景):身高 1.75m,体重 45kg,心率 70,BMI 自动计算,蓝色文字提示偏瘦;
测试 3(标准场景):身高 1.75m,体重 65kg,心率 75,绿色文字标准体态,弹窗提示心率正常;
测试 4(超重场景):身高 1.75m,体重 80kg,心率 105,橙色文字超重,弹窗提示静息心率偏高;
测试 5(肥胖场景):身高 1.75m,体重 100kg,心率 55,红色文字肥胖,弹窗提示心率偏低;
点击重置数据,所有输入框清空,BMI 恢复 0,状态恢复「未检测」。
6.2 UI 效果说明
整体采用极简白色背景,输入框、按钮、结果卡片分层区分,色彩区分健康等级,无复杂动画,轻量化加载,低配模拟器也能流畅运行,无卡顿、无内存溢出问题。
七、项目拓展优化方向
本文基础版本仅实现核心测算逻辑,可基于该项目进行功能拓展,适合课程大作业二次开发:
数据本地持久化:引入 Preferences 数据库,保存多次身体检测记录,新增历史记录页面;
多指标拓展:新增血压、体脂率、每日饮水量、睡眠时间录入与健康评估;
图表可视化:引入ohos-chart图表组件,绘制近 7 天 BMI、心率变化折线图;
权限与健康联动:调用设备健康服务,自动读取手表 / 运动手环心率数据,无需手动输入;
健康计划模块:新增减脂、增肌作息饮食建议页面,根据 BMI 自动推送对应方案;
单位切换功能:身高支持厘米 / 米切换,体重支持斤 / 千克切换;
表单校验增强:限制身高 0.5~2.5m、体重 10~300kg、心率 40~180 区间拦截异常数值;
适配平板 / 折叠屏:增加媒体查询,分栏布局适配大屏设备。
八、总结
本文完整实现了基于 ArkTS 的轻量化健康监测工具SimpleHealthTracker,单页面代码开箱即用,覆盖 ArkUI 基础组件、响应式状态管理、表单交互、数值运算、弹窗提示等鸿蒙入门核心知识点。
重点针对开发过程中两个高频、易卡壳的编译报错做了底层原理拆解与标准化修复方案,解决绝大多数鸿蒙新手实训时无法打包运行的难题。代码兼容 API9、API10 主流低版本 SDK,适配绝大多数课堂实训环境,逻辑分层清晰、注释完整,可直接作为鸿蒙课程设计、期末大作业提交。
同时文章提供多条功能拓展思路,开发者可基于现有框架迭代完善,打造功能更全面的个人健康管理 APP,夯实 ArkTS 声明式 UI 开发、问题排错、项目工程化开发能力。
九、完整项目信息
项目工程名:SimpleHealthTracker
应用中文名称:简易健康监测器
运行页面:entry/src/main/ets/pages/Index.ets
适配 SDK:API 9 / API 10
核心依赖:鸿蒙原生 ArkUI 组件,无第三方依赖

Logo

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

更多推荐