一、引言

进度条是移动端 UI 中最通用的信息展示组件之一。无论是系统监控仪表盘上的 CPU 使用率、文件下载的传输进度、任务完成的百分比、还是存储空间的占用情况,进度条都能以直观的图形方式将抽象的数字转化为可视的比例关系。一个设计良好的进度条不仅展示进度本身,还通过颜色传递语义(红色=危险、绿色=正常),通过动画吸引注意力(实时更新时平滑过渡),通过多样化样式适配不同场景。

在传统开发中,实现不同样式的进度条需要组合 Canvas 绘图、CSS 动画、数学计算等技术,环形进度条尤其复杂——需要计算圆弧路径、极坐标映射、绘制起点和终点。而 HarmonyOS 提供了 Progress 组件——一个内置四种进度条类型的一体化组件,通过声明式 API 即可实现从简单线性条到复杂刻度环的所有样式。

本文通过一个系统性能监控仪表盘 Demo 深入讲解 Progress 组件的核心用法:四种类型各自适用什么场景?如何实现颜色阈值语义?如何用 setInterval 模拟实时数据更新?以及 Progress 组件与其他组件的组合模式。

阅读完本文,你将能够:

  • 区分 Linear/Ring/Capsule/ScaleRing 四种类型的适用场景
  • 掌握 value/total/type 三个核心参数
  • 实现基于阈值的颜色语义(正常→警告→危险)
  • 使用 setInterval + @State 实现实时进度动画
  • 构建系统监控仪表盘的整体方案

二、Progress 组件 API 总览

2.1 构造函数

Progress(options: ProgressOptions)
interface ProgressOptions {
  value: number;        // 当前进度值
  total: number;        // 进度总量(上限)
  type?: ProgressType;  // 进度条类型
  style?: ProgressStyle; // 进度条样式(API 10+,可设置描边宽度等)
}
参数 类型 默认值 说明
value number 必填 当前值,范围 [0, total]
total number 必填 最大值(分母),进度 = value / total
type ProgressType Linear 四种类型之一
style ProgressStyle - 样式配置,如 strokeWidth(环形/刻度环描边宽度)

2.2 ProgressType 四种类型

enum ProgressType {
  Linear,     // 线性进度条——从左到右的横条
  Ring,       // 环形进度条——圆环,从顶部顺时针填充
  Capsule,    // 胶囊进度条——圆角横条,进度值在条内居中显示
  ScaleRing   // 刻度环形进度条——圆环带刻度线
}
类型 外观 典型场景
Linear 水平横条,左到右填充 进度百分比、下载进度、电量条
Ring 圆环弧线,顶部顺时针 仪表盘指标、完成率、目标进度
Capsule 圆角横条,内含文字 存储空间、容量展示、评分分布
ScaleRing 圆环 + 外围刻度线 速度表、转速表、精细化仪表

2.3 链式方法

// 当前值(可动态更新)
.value(value: number): ProgressAttribute

// 进度颜色
.color(value: ResourceColor): ProgressAttribute

// 通用:宽度/高度
.width(value: Length): ProgressAttribute
.height(value: Length): ProgressAttribute

// 通用:圆角(Linear/Capsule 生效)
.borderRadius(value: Length): ProgressAttribute
方法 说明
.value(number) 动态设置进度值,配合 @State 变量实现实时更新
.color(ResourceColor) 进度填充色,支持基于阈值动态切换(绿→橙→红)
.width(Length) 组件宽度。Linear/Capsule 为条长度;Ring/ScaleRing 为圆直径
.height(Length) 组件高度。Linear/Capsule 为条粗细;Ring/ScaleRing 与 width 相同
.borderRadius(Length) 圆角半径,Linear 类型常用 0-4 的圆角

2.4 Progress vs 自建进度条方案

特性 Progress 组件 自建方案
线性进度 ProgressType.Linear 一行搞定 Row + 百分比计算 + CSS 宽高
环形进度 ProgressType.Ring 一行搞定 Canvas 圆弧计算 + 极坐标映射
刻度环形 ProgressType.ScaleRing 一行搞定 Canvas + 复杂刻度算法
胶囊进度 ProgressType.Capsule 一行搞定 Row + borderRadius + 文字居中
颜色语义 .color() 动态切换 手动切换 + 条件逻辑
动画平滑度 内置 Transition 需手动 animateTo

Progress 组件适合所有标准进度展示场景。只有在需要高度定制的进度视觉效果(如圆角方形节点、渐变色彩填充、自定义刻度形状)时,才考虑自建方案。
在这里插入图片描述

三、Demo 设计:系统性能监控

3.1 功能概述

Demo 是一个系统性能监控仪表盘,模拟服务器或设备监控面板:

  1. CPU 使用率 — Linear:线性进度条展示 CPU 占用百分比,带百分比数值和颜色状态标签
  2. 内存使用 — Ring:环形进度条展示内存使用量(GB),120vp 直径
  3. 磁盘空间 — Capsule:胶囊进度条展示存储占用,内含文字 + 剩余空间
  4. 运行进程 — ScaleRing:刻度环展示进程数量,140vp 直径
  5. 颜色阈值:三项指标根据实际值自动变色——正常(蓝色)、警告(橙色)、危险(红色)
  6. 模拟监控:点击"开始监控"按钮启动 setInterval(1.5 秒间隔),四个指标随机变化模拟实时数据

3.2 交互点

# 交互 说明
1 开始/停止监控 setInterval 模拟实时数据流,四种进度条同步变化
2 颜色阈值变化 数值跨越 60%/85% 阈值时颜色实时切换(蓝→橙→红)
3 四种类型对比 Linear/Ring/Capsule/ScaleRing 同时展示,直观对比差异
4 状态标签 每个进度条旁显示"正常/警告/危险"标签和数值
在这里插入图片描述

四、完整代码实现

4.1 状态变量

@State cpuValue: number = 0;
@State memoryValue: number = 0;
@State storageValue: number = 0;
@State runningValue: number = 0;
@State isRunning: boolean = false;
private timerId: number = -1;

关键说明:

  • 四个 @State 数值变量分别对应 CPU(0-100)、内存(0-16384 MB = 16 GB)、磁盘(0-256 GB)、进程数(0-120)
  • isRunning 控制按钮文字和 setInterval 的启停
  • timerId 保存 setInterval 返回的定时器 ID,用于 clearInterval 停止定时器

4.2 颜色阈值逻辑

getProgressColor(value: number, max: number): string {
  const pct = value / max;
  if (pct >= 0.85) return '#FF4D4F';
  if (pct >= 0.6) return '#FF9800';
  return '#1677FF';
}

getColorLabel(value: number, max: number): string {
  const pct = value / max;
  if (pct >= 0.85) return '危险';
  if (pct >= 0.6) return '警告';
  return '正常';
}

颜色映射逻辑:value / max 计算百分比,然后按阈值分级:

  • < 60%:蓝色(#1677FF)+ “正常”——系统运行健康
  • 60% ~ 85%:橙色(#FF9800)+ “警告”——需要注意,负载较高
  • ≥ 85%:红色(#FF4D4F)+ “危险”——接近极限,有风险

这个颜色方案遵循通用的交通灯语义,让用户无需阅读数字就能快速判断系统状态。颜色同时作用于 Progress 组件的填充色和旁边的状态标签。

4.3 模拟数据更新

startMonitor() {
  this.isRunning = true;
  this.timerId = setInterval(() => {
    this.cpuValue = Math.floor(Math.random() * 100);
    this.memoryValue = Math.floor(Math.random() * 16384);
    this.storageValue = Math.floor(Math.random() * 256);
    this.runningValue = Math.floor(Math.random() * 120);
  }, 1500);
}

stopMonitor() {
  this.isRunning = false;
  clearInterval(this.timerId);
}

aboutToDisappear() {
  if (this.isRunning) {
    clearInterval(this.timerId);
  }
}

关键细节:

  • setInterval 每 1.5 秒执行一次,模拟监控数据轮询。间隔不宜太短(高频更新增加渲染负担)也不宜太长(失去实时感),1-2 秒是仪表盘的合理区间
  • Math.random() 生成的是均匀分布的随机数,真实监控数据通常是平滑变化的。Demo 使用随机值是为了演示颜色变化的动态效果,实际应用中应从 @ohos.systemCapability 等系统 API 获取真实数据
  • aboutToDisappear() 是组件的生命周期回调,在页面即将销毁时调用。这里用于清理定时器,防止页面销毁后定时器仍在运行导致内存泄漏

4.4 Linear 线性进度条 — CPU 使用率

Progress({
  value: this.cpuValue,
  total: 100,
  type: ProgressType.Linear
})
  .value(this.cpuValue)
  .color(this.getProgressColor(this.cpuValue, 100))
  .height(8)
  .borderRadius(4)

配置要点:

  • total: 100 意味着 value 就是百分比,直接等于 CPU 占用率
  • .height(8) + .borderRadius(4):8vp 高度的进度条配上 4vp 圆角,形成圆润的横条。高度不宜太小(看不清)也不宜太大(显得笨重),6-10vp 是常用范围
  • .color() 动态绑定颜色,随着 CPU 值变化实时切换

Linear 类型的进度条适合横排展示单项指标,旁边放数值和标签形成信息密度合适的行。

4.5 Ring 环形进度条 — 内存使用

Progress({
  value: this.memoryValue,
  total: 16384,
  type: ProgressType.Ring
})
  .value(this.memoryValue)
  .color(this.getProgressColor(this.memoryValue, 16384))
  .width(120)
  .height(120)

配置要点:

  • total: 16384 表示 16 GB(16384 MB),value 为当前使用的 MB 数
  • .width(120).height(120):环形进度条的宽度和高度相等形成正圆。120vp 是仪表盘的常用尺寸——不大不小,配合下方文字形成视觉平衡
  • Ring 类型的进度条从顶部(12 点钟方向)开始顺时针填充。如果 value=total/2(50%),圆环从顶部顺时针画半圈到底部

Ring 适合展示单个指标的核心数值,视觉上比 Linear 更突出、更具仪表感。配合下方大号数值文字,形成"图形 + 数据"的双重展示。

4.6 Capsule 胶囊进度条 — 磁盘空间

Progress({
  value: this.storageValue,
  total: 256,
  type: ProgressType.Capsule
})
  .value(this.storageValue)
  .color(this.getProgressColor(this.storageValue, 256))
  .width('100%')
  .height(32)
  .borderRadius(16)

配置要点:

  • total: 256 表示 256 GB 总空间,value 为已用空间
  • .height(32).borderRadius(16):32vp 高度 + 16vp 圆角 = 完美胶囊形(圆角半径 = 高度的一半)
  • .width('100%'):撑满容器,适合作全宽展示

Capsule 类型与 Linear 不同:Linear 是细长的横条,Capsule 是较粗的圆角横条且在条内居中显示文字(如 “45/256”)。它更像一个"统计标签"而非"进度指示器",适合存储空间、容量展示等场景。

4.7 ScaleRing 刻度环形进度条 — 运行进程

Progress({
  value: this.runningValue,
  total: 120,
  type: ProgressType.ScaleRing
})
  .value(this.runningValue)
  .color(this.getProgressColor(this.runningValue, 120))
  .width(140)
  .height(140)

配置要点:

  • ScaleRing 在 Ring 的基础上添加了外围刻度线——每个刻度代表一个单位,让用户更精确地判断进度
  • .width(140).height(140):比 Ring 略大(140 vs 120),因为刻度线需要额外空间
  • ScaleRing 适合需要精确读取数值的场景(如速度表、转速表),刻度线使用户无需依赖文字就能大致判断百分比

4.8 控制按钮

if (this.isRunning) {
  Button('⏸ 停止监控')
    .fontSize(16)
    .fontColor('#FFFFFF')
    .backgroundColor('#FF4D4F')
    .borderRadius(22)
    .height(44)
    .layoutWeight(1)
    .onClick(() => { this.stopMonitor(); })
} else {
  Button('▶ 开始监控')
    .fontSize(16)
    .fontColor('#FFFFFF')
    .backgroundColor('#1677FF')
    .borderRadius(22)
    .height(44)
    .layoutWeight(1)
    .onClick(() => { this.startMonitor(); })
}

按钮通过 isRunning 切换显示——正在监控时显示红色"停止监控",未监控时显示蓝色"开始监控"。这个二元切换的设计避免了同时出现两个按钮造成的混淆。

五、关键技术点详解

5.1 value + total 的进度计算

Progress 组件内部通过 value / total 计算进度百分比。边界情况:

  • value = 0:进度为空(不填充),如 Linear 条完全空白、Ring 完全空心
  • value = total:进度为满(完全填充),如 Ring 的圆弧闭合为完整圆
  • value > total:进度截断为 100%,不会超出
  • value < 0:进度截断为 0%,不会反向填充

注意valuetotal 是整数类型。如果需要小数精度(如 3.5/10),可以在业务层乘以 10 使用(如 35/100 = 35%)。

5.2 .value() 方法的双重身份

.value() 方法既是构造函数参数也是链式方法,但两者有细微区别:

// 方式 1:构造函数中传 value(初始值)
Progress({ value: 50, total: 100, type: ProgressType.Linear })

// 方式 2:链式方法 .value()(动态更新)
Progress({ total: 100, type: ProgressType.Linear })
  .value(this.cpuValue)  // 通过 @State 变量动态更新

构造函数中的 value 是初始值,链式方法 .value() 用于将 @State 变量绑定到组件。当 @State 变量变化时,Progress 组件自动重新渲染并平滑过渡到新值。

5.3 Progress 动画的平滑过渡

Progress 组件在 @State 变量变化时会自动触发过渡动画——不是生硬的跳变,而是约 300ms 的平滑过渡。这意味着用 setInterval 更新的进度条不会出现抖动,值的每次变化都以流畅的动画呈现。

如果不需要动画(如首次加载时从 0 跳到 50 不希望有过渡),可以将 .animation({ duration: 0 }) 作用于 Progress 组件来禁用动画。

5.4 Ring 环形进度条的描边宽度控制

Ring 和 ScaleRing 类型通过 ProgressStyle 控制描边宽度:

Progress({
  value: this.memoryValue,
  total: 16384,
  type: ProgressType.Ring,
  style: { strokeWidth: 12 }  // 描边宽度 12vp
})
  • strokeWidth 默认值约 8-10vp。值越大,弧线越粗;值越小,弧线越细
  • Ring 和 ScaleRing 的描边是沿着圆弧路径绘制的,所以描边宽度影响的是弧线的粗细,而非圆的半径
  • Capsule 和 Linear 类型不支持 strokeWidth

5.5 四种类型的语义选择

选择哪种 Progress 类型取决于你想传达的信息:

场景 推荐类型 原因
CPU/内存百分比 Linear 节省空间,适合行内展示
核心仪表指标 Ring 视觉突出,仪表感强
存储空间/容量 Capsule 内含文字,信息密度高
速度/转速/精度指标 ScaleRing 刻度线辅助精读
多指标面板 Linear + Ring 混用 区分主次指标

六、运行效果

6.1 初始状态

页面顶部标题栏"📊 系统监控",下方组件介绍卡片,然后是蓝色"开始监控"按钮。四个指标区域(CPU-Linear、内存-Ring、磁盘-Capsule、进程-ScaleRing)初始值均为 0,进度条均显示为空状态。

6.2 开始监控

点击"开始监控"→ 按钮变为红色"停止监控"。四种进度条每 1.5 秒同步更新一次,数值随机变化。

6.3 颜色阈值效果

CPU 值为 45% → Linear 进度条蓝色,标签"正常"蓝色。内存值为 78%(约 12.8 GB)→ Ring 进度条橙色,标签"警告"橙色。磁盘值为 92%(约 235 GB)→ Capsule 进度条红色,标签"危险"红色。三个指标的不同颜色让系统状态一目了然。

6.4 停止监控

点击"停止监控"→ 按钮恢复蓝色"开始监控",进度条数值定格在当前值,颜色基于当前数值保持不变。

七、最佳实践与注意事项

7.1 何时使用 Progress

  • 系统监控:CPU、内存、磁盘、网络的实时使用率
  • 任务进度:文件上传/下载、数据导入/导出、安装进度
  • 目标完成度:每日步数达标、预算使用比例、学习进度
  • 容量展示:存储空间已用/总量、云盘配额使用情况

7.2 设计颜色方案

// 推荐的三级颜色方案
const COLOR_SAFE = '#1677FF';    // 蓝——正常范围
const COLOR_WARN = '#FF9800';    // 橙——需要注意
const COLOR_DANGER = '#FF4D4F';  // 红——立即关注

不要使用黄色作为进度色(对比度不足,白色文字看不清)。蓝色→橙色→红色是最通用的选择,在各种背景下都足够醒目。

7.3 常见问题

Q: Progress 可以显示百分比文字吗?

A: 组件本身不提供文字显示功能(Capsule 除外,它内置显示 “value/total” )。需要在 Progress 旁边或下方使用 Text 组件手动显示百分比。

Q: 如何实现下载进度条的双色效果(已下载一侧、未下载一侧)?

A: Progress 只支持单色(.color()),不支持多段颜色。如需多色方案,可以用两个重叠的 Progress 或自定义 Row 实现。

Q: ScaleRing 的刻度数量可以自定义吗?

A: 目前刻度数量由 total 值自动计算。如需特定刻度数量,可以调整 total 来控制刻度密度(total 越大,刻度越密)。

Q: Ring 可以改成从底部或左侧开始填充吗?

A: 不可以。Ring 和 ScaleRing 的填充起点固定为 12 点钟方向(顶部),顺时针填充。无法自定义起点角度。如需特殊起点,需要使用 Canvas 自定义绘制。

7.4 性能注意事项

  • setInterval 中的 @State 更新会触发组件树重新渲染。本 Demo 中四个指标分别独立更新,每次只重新渲染对应的 Progress 组件(ArkUI 的差异化更新机制)
  • 如果同时更新大量 Progress 实例(如列表中上百个),建议使用 LazyForEach 懒加载渲染
  • 页面销毁时必须 clearInterval 清理定时器,否则会造成内存泄漏

八、拓展思考

8.1 从模拟数据到真实数据

Demo 使用 Math.random() 模拟监控数据。在真实应用中,可以通过以下 API 获取系统数据:

import { systemDateTime } from '@kit.BasicServicesKit';
import { batteryInfo } from '@kit.BasicServicesKit';
import { deviceInfo } from '@kit.BasicServicesKit';
// 或通过 Native API 调用获取 CPU/内存信息

8.2 多指标数据看板

单个 Progress 是基础组件,多个 Progress 组合则形成仪表盘。更完整的仪表盘可以包括:

  • 数据对比:当前值 vs 历史均值,通过两个 Progress 或一个 Progress + 一条参考线展示
  • 趋势指示:Progress 旁边加箭头表示环比涨跌
  • 报警联动:当 Progress 进入红色阈值时触发通知或弹窗

8.3 与其他组件的配合

  • Progress + Text:标准模式——进度条 + 百分比数字 + 标签文字
  • Progress + Gauge:Gauge 展示核心指标(弧线仪表),Progress 展示辅助指标(横条)
  • Progress + List:多个 Progress 在列表中展示多项指标,每行一个 Linear
  • Progress + CustomDialog:弹窗中的下载进度条

九、总结

本文通过一个系统性能监控仪表盘的实战 Demo,深入讲解了 HarmonyOS Progress 进度条组件的四种类型及其核心用法:

  1. 四种类型:Linear(线性)、Ring(环形)、Capsule(胶囊)、ScaleRing(刻度环),各自适用不同的展示场景
  2. 进度计算value / total 决定填充比例,@State 驱动动态更新
  3. 颜色语义:基于阈值的三级颜色映射(蓝→橙→红),强化信息传达效率
  4. 实时模拟setInterval + @State 实现动态数据更新,自动动画过渡
  5. 生命周期管理aboutToDisappear 清理定时器,防止内存泄漏

Progress 是 ArkUI 进度展示的标准解决方案。从系统监控到文件下载,从任务进度到容量展示,Progress 以其丰富的类型选择和简洁的声明式 API,帮助开发者用最小代码实现最直观的进度可视化。希望本文能帮助你在实际项目中高效运用 Progress 组件。


相关文章


本文基于 HarmonyOS NEXT API 24 编写,代码经 DevEco Studio 6.1.1 编译验证通过。

Logo

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

更多推荐