news 2026/7/19 3:08:28

HarmonyOS ArkUI Progress 进度条:5 种类型与动画演示

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HarmonyOS ArkUI Progress 进度条:5 种类型与动画演示

系列:鸿蒙 HarmonyOS 6.1 新特性实战 · 第 36 篇

Progress 组件支持 5 种不同的视觉类型,从线形到环形再到胶囊形,配合定时器可实现丝滑的进度动画。本篇完整演示所有类型,并给出通用的进度动画模式和生命周期清理最佳实践。

运行效果

初始状态,展示 5 种进度条类型(进度 0%):

点击“开始演示“后,进度动画进行中:

一、Progress 5 种类型

// Linear 线形(最常用,适合页面顶部加载进度) Progress({ value: 60, total: 100, type: ProgressType.Linear }) .width('100%').height(8) .color('#0066ff').backgroundColor('#e0e8ff') // Ring 环形(适合圆形 Loading 指示) Progress({ value: 60, total: 100, type: ProgressType.Ring }) .width(80).height(80) .color('#0066ff').backgroundColor('#e0e8ff') .style({ strokeWidth: 8 }) // Eclipse 月食形(视觉特殊,用于特定场景) Progress({ value: 60, total: 100, type: ProgressType.Eclipse }) .width(80).height(80) .color('#8e44ad').backgroundColor('#f0e0ff') // ScaleRing 刻度环形(带刻度线,精密进度) Progress({ value: 60, total: 100, type: ProgressType.ScaleRing }) .width(80).height(80) .color('#e67e22').backgroundColor('#fff3e0') .style({ strokeWidth: 8, scaleCount: 20, scaleWidth: 3 }) // Capsule 胶囊形(适合下载进度、文件传输) Progress({ value: 60, total: 100, type: ProgressType.Capsule }) .width('100%').height(32) .color('#27ae60').backgroundColor('#e0ffe8')

二、Ring + Stack 显示百分比数字

环形进度条中间叠加文字是常见需求,用Stack实现:

Stack() { Progress({ value: this.progress, total: 100, type: ProgressType.Ring }) .width(80).height(80) .color('#e74c3c').backgroundColor('#ffe0e0') .style({ strokeWidth: 8 }) Text(this.progress.toString() + '%') .fontSize(14).fontColor('#e74c3c').fontWeight(FontWeight.Bold) }

三、进度动画:setInterval + aboutToDisappear

进度动画核心是用setInterval定期更新@State,页面销毁时必须清理定时器:

@State progress: number = 0 @State running: boolean = false private timer: number = -1 // 必须在 aboutToDisappear 清理定时器 aboutToDisappear(): void { if (this.timer >= 0) { clearInterval(this.timer) } } startProgress(): void { this.progress = 0 this.running = true this.timer = setInterval(() => { this.progress += 2 if (this.progress >= 100) { this.progress = 100 this.running = false clearInterval(this.timer) this.timer = -1 } }, 60) // 每 60ms +2%,约 3 秒完成 }

为什么timer初始值用 -1?避免用0导致与合法 timer ID 冲突(部分系统会返回 0 作为首个 timer ID),用 -1 作为“未启动“哨兵值更安全。

四、style 属性

.style()支持的参数因类型而异:

// Linear / Capsule .style({ strokeWidth: 14, enableSmoothEffect: true }) // Ring .style({ strokeWidth: 8 }) // ScaleRing .style({ strokeWidth: 8, scaleCount: 20, scaleWidth: 3 })

enableSmoothEffect: true开启线形进度条的平滑动效(默认开启)。

完整代码

@Entry @Component struct Index { @State progress: number = 0 @State running: boolean = false private timer: number = -1 aboutToDisappear(): void { if (this.timer >= 0) { clearInterval(this.timer) } } startProgress(): void { this.progress = 0 this.running = true this.timer = setInterval(() => { this.progress += 2 if (this.progress >= 100) { this.progress = 100 this.running = false clearInterval(this.timer) this.timer = -1 } }, 60) } build() { Scroll() { Column({ space: 20 }) { Text('Progress 全类型进度条') .fontSize(22).fontWeight(FontWeight.Bold).fontColor('#1a1a1a') Text('当前进度:' + this.progress.toString() + '%') .fontSize(16).fontColor('#0066ff').fontWeight(FontWeight.Bold) Button(this.running ? '进行中...' : '开始演示') .width('100%').height(48).backgroundColor(this.running ? '#aaa' : '#0066ff').fontColor('#fff') .enabled(!this.running).onClick(() => { this.startProgress() }) // Linear Column({ space: 8 }) { Text('一、Linear 线形').fontSize(15).fontWeight(FontWeight.Bold).fontColor('#333') Progress({ value: this.progress, total: 100, type: ProgressType.Linear }) .width('100%').height(8).color('#0066ff').backgroundColor('#e0e8ff') Progress({ value: this.progress, total: 100, type: ProgressType.Linear }) .width('100%').height(14).color('#27ae60').backgroundColor('#e0ffe8') .style({ strokeWidth: 14, enableSmoothEffect: true }) } .padding(12).backgroundColor('#fff').borderRadius(8).width('100%') .border({ width: 1, color: '#e0e0e0' }).alignItems(HorizontalAlign.Start) // Ring Column({ space: 8 }) { Text('二、Ring 环形').fontSize(15).fontWeight(FontWeight.Bold).fontColor('#333') Row({ space: 24 }) { Column({ space: 4 }) { Progress({ value: this.progress, total: 100, type: ProgressType.Ring }) .width(80).height(80).color('#0066ff').backgroundColor('#e0e8ff') .style({ strokeWidth: 8 }) Text('默认').fontSize(12).fontColor('#666') } Column({ space: 4 }) { Stack() { Progress({ value: this.progress, total: 100, type: ProgressType.Ring }) .width(80).height(80).color('#e74c3c').backgroundColor('#ffe0e0') .style({ strokeWidth: 8 }) Text(this.progress.toString() + '%') .fontSize(14).fontColor('#e74c3c').fontWeight(FontWeight.Bold) } Text('叠加文字').fontSize(12).fontColor('#666') } } } .padding(12).backgroundColor('#fff').borderRadius(8).width('100%') .border({ width: 1, color: '#e0e0e0' }).alignItems(HorizontalAlign.Start) // Eclipse + ScaleRing Column({ space: 8 }) { Text('三、Eclipse 月食 / ScaleRing 刻度环').fontSize(15).fontWeight(FontWeight.Bold).fontColor('#333') Row({ space: 24 }) { Column({ space: 4 }) { Progress({ value: this.progress, total: 100, type: ProgressType.Eclipse }) .width(80).height(80).color('#8e44ad').backgroundColor('#f0e0ff') Text('Eclipse').fontSize(12).fontColor('#666') } Column({ space: 4 }) { Progress({ value: this.progress, total: 100, type: ProgressType.ScaleRing }) .width(80).height(80).color('#e67e22').backgroundColor('#fff3e0') .style({ strokeWidth: 8, scaleCount: 20, scaleWidth: 3 }) Text('ScaleRing').fontSize(12).fontColor('#666') } } } .padding(12).backgroundColor('#fff').borderRadius(8).width('100%') .border({ width: 1, color: '#e0e0e0' }).alignItems(HorizontalAlign.Start) // Capsule Column({ space: 8 }) { Text('四、Capsule 胶囊形').fontSize(15).fontWeight(FontWeight.Bold).fontColor('#333') Progress({ value: this.progress, total: 100, type: ProgressType.Capsule }) .width('100%').height(32).color('#27ae60').backgroundColor('#e0ffe8') } .padding(12).backgroundColor('#fff').borderRadius(8).width('100%') .border({ width: 1, color: '#e0e0e0' }).alignItems(HorizontalAlign.Start) } .padding(20).width('100%') } .width('100%').height('100%').backgroundColor('#f5f5f5') } }

API 速查

属性/方法说明
Progress({ value, total, type })创建进度条
.color('#0066ff')进度颜色
.backgroundColor('#e0e8ff')轨道背景色
.style({ strokeWidth, ... })样式配置(按类型不同)
ProgressType.Linear线形
ProgressType.Ring环形
ProgressType.Eclipse月食形
ProgressType.ScaleRing刻度环形
ProgressType.Capsule胶囊形

小结

  • Linear 是最通用的:加载进度、下载进度首选,简洁明了
  • Ring + Stack = 圆形进度:用 Stack 叠加 Text 显示百分比,是标准做法
  • 定时器必须在 aboutToDisappear 清理:否则页面离开后定时器仍在跑,浪费资源可能崩溃
  • timer 初始值用 -1 而非 0:0 可能是有效 timer ID,用哨兵值 -1 避免误清理

上一篇:Slider 与 Rating 实战 | 下一篇:DatePicker / TimePicker 日期时间选择器完全指南

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/19 3:08:14

Unity动画重定向实战:利用Avatar实现多角色动画复用

1. 项目概述:为什么需要动画复用?在Unity项目里,尤其是角色扮演、多人在线或者需要大量NPC的游戏里,动画制作绝对是个大头。你想想,一个角色从走路、跑步、跳跃到攻击、受击、死亡,少说也得几十个动画片段。…

作者头像 李华
网站建设 2026/7/19 3:07:19

Python登录模块开发:安全认证与实现指南

1. Python登录模块开发全指南 登录功能是任何需要用户身份验证的系统中最基础也最关键的模块之一。作为Python开发者,我们经常需要为各种应用实现安全可靠的登录系统。本文将深入探讨如何从零开始构建一个完整的Python登录模块,涵盖从基础原理到高级安全…

作者头像 李华
网站建设 2026/7/19 3:06:54

对比实测10款降AIGC平台:一键锁定高效助手!

AI写作工具让论文写作和内容创作变得又快又好,越来越多的学生和职场人开始依赖它来提升效率。但随着技术发展,高校、平台和期刊对AI生成内容的检测标准也越来越严格。不少用户发现,自己用AI写的文章经常被系统标记为“疑似AI生成”&#xff0…

作者头像 李华
网站建设 2026/7/19 3:06:44

Claude Fable 5与DeepSeek v4-flash模型对比:场景选择与工程实践

最近在测试几个新模型时,我发现了一个有趣的现象:很多开发者拿到一个新模型,第一反应是跑分、测极限、对比参数表,但真正决定一个模型能否融入工作流的,往往是一些更细微的体验差异。就像这次同时测试 Claude Fable 5 …

作者头像 李华
网站建设 2026/7/19 3:06:33

pub.towardsai.net技术解析:静态文档发布枢纽架构与实践

1. 项目概述:一个被广泛误读的域名,到底在做什么?“pub.towardsai.net”——这个字符串乍看像一段技术文档里的引用链接,又像某个实验性服务的临时地址,甚至有人第一反应是“是不是漏了https?是不是打错了&…

作者头像 李华
网站建设 2026/7/19 3:06:15

五年走访东莞胶袋厂,发现的专业细节

我这五年,基本上都在东莞的工业区里窜,跟胶袋厂打交道。你说咱这行,包装袋看着不起眼,可真要把它弄明白,门道深着呢。 刚入行那会儿,我踩过不少坑。比如,接了个大单,客户要一批真空袋…

作者头像 李华