# 鸿蒙 HarmonyOS 应用开发实战(第34期)|计步器(Pedometer)— Progress Ring 环形进度与运动数据看板

📅 2026/7/30 1:59:55
# 鸿蒙 HarmonyOS 应用开发实战(第34期)|计步器(Pedometer)— Progress Ring 环形进度与运动数据看板
一、应用概述计步器Pedometer是一款模拟步数追踪的健康应用。它通过随机算法模拟走路步数增长利用环形进度条Progress Ring直观展示日行万步的完成进度并同步计算行走距离公里和消耗的卡路里。用户可以通过「开始走路」和「暂停」按钮控制模拟过程「重置」按钮清空数据重新开始。本应用是 HarmonyOSProgress组件Ring环形类型的完美应用场景。相比于传统的水平进度条环形进度条具有更强的视觉冲击力和空间利用率广泛用于运动健康、设备状态、任务完成度等场景。此外应用还展示了setInterval高频更新每 500ms与数据衍生的高级用法。二、技术架构与组件树2.1 整体架构Entry Component struct index34 ├── Column (根容器) │ ├── Row (顶部导航栏) │ └── Column (主内容区, 居中) │ ├── Stack (环形进度 中心数据) │ │ ├── Progress (Ring 类型, 200×200) │ │ └── Column (中心内容) │ │ ├── Text (, 40px) │ │ ├── Text (steps 数字, 36px) │ │ └── Text (步) │ ├── Text (状态提示: 还剩 X 步 / 达成目标) │ ├── Row (统计面板) │ │ ├── Column (公里数) │ │ └── Column (卡路里) │ ├── Row (按钮组) │ │ ├── Button (▶️ 开始走路 / ⏸️ 暂停) │ │ └── Button ( 重置) │ └── Row (目标显示)2.2 状态变量与常量State steps: number 0; // 当前步数 State target: number 10000; // 目标步数默认一万 State isWalking: boolean false; // 是否行走中 intervalId: number -1; // 定时器 ID核心变量仅三个State但通过 getter 衍生出了progress、kilometers、calories、status四个计算属性体现了「最小化状态、最大化衍生」的 ArkTS 最佳实践。三、核心代码深度解析3.1 模拟行走的定时器逻辑startWalking(): void { if (this.isWalking) return; this.isWalking true; this.intervalId setInterval((): void { this.steps Math.floor(Math.random() * 5) 1; if (this.steps 99999) { this.stopWalking(); } }, 500); } stopWalking(): void { clearInterval(this.intervalId); this.isWalking false; }模拟算法每 500ms步数增加Math.floor(Math.random() * 5) 1即每次增加 1~5 步均匀分布。这种算法模拟了真实走路时步频的微小波动——每秒大约增加 2~10 步相当于每分钟 120~600 步接近人类正常步行速度约每分钟 100~120 步。安全上限当steps 99999时自动停止防止步数溢出或 UI 显示异常。99999 是五位数上限超过了常见的日行步数范围一般不超过 5 万步。3.2 派生数据的计算属性get progress(): number { return Math.min((this.steps / this.target) * 100, 100); } get kilometers(): string { return (this.steps * 0.75 / 1000).toFixed(2); } get calories(): number { return Math.floor(this.steps * 0.04); } get status(): string { if (this.steps this.target) return 达成目标; return 还剩 (this.target - this.steps) 步; }属性公式说明progresssteps/target × 100上限 100%环形进度条百分比kilometerssteps × 0.75m / 1000假设步幅 0.75 米保留两位小数caloriessteps × 0.04假设每步消耗 0.04 千卡status条件判断达目标时庆祝否则显示剩余步数参数说明步幅 0.75 米是亚洲成年人的平均步幅每步 0.04 千卡是基于体重 60kg 的估算值这些参数可以在未来版本中改为用户可配置项。3.3 Progress Ring 环形进度条Stack() { Progress({ value: this.progress, total: 100, type: ProgressType.Ring }) .width(200).height(200) .style({ strokeWidth: 18 }) .color(#4CAF50) Column() { Text().fontSize(40) Text(this.steps.toLocaleString()).fontSize(36).fontWeight(FontWeight.Bold) Text(步).fontSize(16).fontColor(#888) } }Progress 组件详解Progress是 HarmonyOS 内置的进度条组件支持四种类型ProgressType.Linear水平线性进度条ProgressType.Ring环形进度条ProgressType.Eclipse椭圆形进度条ProgressType.Scale刻度盘进度条本例使用Ring类型主要参数参数值说明valuethis.progress当前进度值0-100total100最大值typeProgressType.Ring环形样式style.strokeWidth18环的粗细pxcolor‘#4CAF50’进度条颜色绿色Stack 组合技巧将 Progress 和 Column 放在同一个 Stack 中Column 位于 Progress 之上后声明通过居中对齐实现步数数字显示在环形中心的效果。这种「环形外圈 数据内芯」的设计模式在智能手表表盘和健康应用中被广泛使用。3.4 条件渲染的按钮if (!this.isWalking) { Button() { Text(▶️ 开始走路).fontSize(18).fontColor(#fff) }.width(140).height(48).borderRadius(24).backgroundColor(#4CAF50) .onClick(() this.startWalking()) } else { Button() { Text(⏸️ 暂停).fontSize(18).fontColor(#fff) }.width(140).height(48).borderRadius(24).backgroundColor(#FF9800) .onClick(() this.stopWalking()) }与第 32 期的间隔计时器类似这里也使用了条件渲染来切换按钮。但有一个细微差异这里使用了Button 的尾随 lambda 语法Button() { Text(...) }而不是简写形式Button(文本)。尾随 lambda 允许在按钮内部嵌套复杂的子组件布局如同时显示图标和文字。四、HarmonyOS 特性分析4.1 Progress 组件的进阶用法Progress.Ring 的style属性支持更丰富的定制.style({ strokeWidth: 18, // strokeColor: Color.Grey, // 未完成部分的颜色默认灰色 // scaleCount: 60, // Scale 类型时的刻度数量 // scaleWidth: 4 // Scale 类型时的刻度宽度 })当前代码使用了默认的灰色轨道 绿色进度视觉效果清爽。如果要更精确地控制样式可以为未完成部分指定strokeColor。4.2 高频定时器的性能考量setInterval间隔设置为 500ms比常规的 1000ms 快一倍这是为了模拟更自然的步频增长。高频定时器需要注意避免耗时操作回调中只做简单的加法运算不做网络请求或文件 I/O合理的上限保护steps 99999自动停止组数上限步数最大不超过 99999避免 UI 显示溢出生命周期清理aboutToDisappear中清除定时器虽然本页未显式声明但应该补充4.3 toLocaleString 的本地化格式化Text(this.steps.toLocaleString())toLocaleString()会根据系统语言环境自动添加千位分隔符。在中文环境下10000显示为10,000让大数字更易读。这是 JavaScript 内置 API在 ArkTS 中完全可用。五、UI/UX 设计与最佳实践5.1 数据看板的布局策略主界面分为四个信息层级第一层级环形进度 步数最醒目视觉焦点第二层级状态文字还剩 X 步 / 达成目标第三层级衍生数据公里数、卡路里第四层级操作按钮控制模拟过程这种从「核心数据 → 状态提示 → 衍生数据 → 操作控制」的布局顺序让用户先看到最重要的信息再逐步了解细节最后决定操作。5.2 色彩与视觉设计主色调绿色#4CAF50象征健康、运动、活力背景色#f0faf0极浅的绿色背景与主题呼应又不喧宾夺主数据卡片白色背景 圆角清爽简洁按钮颜色绿色开始、橙色暂停、灰色重置功能与颜色一一对应5.3 防重复启动保护if (this.isWalking) return;startWalking()的第一行就是防重复保护。如果用户快速多次点击「开始走路」按钮只有第一次有效。这是幂等性设计的体现——同一个操作执行多次和执行一次的结果相同。六、可扩展思路真实传感器集成使用ohos.sensor接入加速度传感器实现真实计步而非模拟。每日目标持久化使用ohos.data.preferences保存每日步数和目标显示周/月趋势图表。成就系统设定里程碑如 10 万步、100 万步达到后解锁徽章。社交排行榜接入云服务与好友比拼步数。运动模式区分走路/跑步模式不同模式使用不同的步幅和卡路里算法。七、总结计步器应用以 112 行代码构建了一个完整的运动数据看板。它的技术亮点包括Progress.Ring 环形进度条在健康类应用中大放异彩的组件高频数据模拟500ms 间隔 随机增量模拟真实步频多维度数据衍生从步数原始值衍生出进度、距离、卡路里Stack 环形中心组合环形外圈 数据内芯的通用设计模式条件渲染的按钮切换同一位置不同状态的按钮展示这个应用的架构模式——环形进度 中心数据 衍生统计——可以直接复用到卡路里追踪、睡眠监测、屏幕使用时间等各类数据看板类应用中。下一期我们将从身体健康转向情绪健康探讨一个充满温暖的设计——情绪追踪Mood Tracker看如何用 emoji 表情和 ForEach 循环构建情绪记录系统。本文是 HarmonyOS 应用开发实战系列第 34 期更多内容请关注专栏。