HarmonyOS鸿蒙Next中怎么解决Progress组件配合animateTo实现循环动画无反应问题
HarmonyOS鸿蒙Next中怎么解决Progress组件配合animateTo实现循环动画无反应问题
【问题现象】
使用Progress组件配合animateTo来实现进度条循环动画,动画效果失效无反应。代码:
/** 进度条最小值 */
const PROGRESS_MIN = 0
/** 进度条最大值 */
const PROGRESS_MAX = 100
@Entry
@Component
struct ProgressAnim {
/** 进度条当前值 */
@State progressValue: number = PROGRESS_MIN
build() {
Column({ space: 15 }) {
Progress({
value: this.progressValue, // 进度条当前进度值
total: PROGRESS_MAX, // 进度条总长
type: ProgressType.Ring, // 进度条类型,分为Linear线性样式、ScaleRing环形有刻度样式、Ring环形无刻度样式、Eclipse圆形样式、Capsule胶囊样式
})
.style({
strokeWidth: 10, // 进度条宽度,默认4vp
enableSmoothEffect: true // 进度平滑动效的开关。开启平滑动效后设置进度,进度会从当前值渐变至设定值,否则进度从当前值突变至设定值,默认值true
})
.width(100) // 进度条组件宽度
.color('# A97CF9') // 进度条前景色
.backgroundColor(Color.White) // 进度条背景色
Button('开始动画')
.onClick(() => {
this.getUIContext()?.animateTo({
duration: 2000,
iterations: -1, // 设置-1表示动画无限循环
}, () => {
this.progressValue = PROGRESS_MAX
})
})
}
.width('100%')
.padding({ top: 5 })
.backgroundColor(Color.Gray)
}
}
【背景知识】
-
Progress进度条组件:用于显示内容加载或操作处理等进度。可以有多种表现形式,官方提供胶囊型、环形有刻度、环形无刻度、圆形,且支持自定义图形样式。
-
显式动画animateTo:提供全局animateTo显式动画接口来指定由于闭包代码导致的状态变化插入过渡动效。同属性动画,布局类改变宽高的动画,内容都是直接到终点状态,例如文字、Canvas的内容等。
-
定时器:setInterval()方法重复调用一个函数或执行一个代码片段,在每次调用之间具有固定的时间间隔。
此方法返回一个间隔ID,其唯一地标识时间间隔,因此你可以稍后通过调用clearInterval()来移除它。
【定位思路】
animateTo适用于组件自身属性动画场景(如尺寸、颜色改变等),问题代码使用animateTo改变Progress组件的进度值,结果是进度条从0到100动画仅执行一次。可见不支持使用animateTo控制Progress组件进度条循环效果。
【解决方案】
使用定时器来控制Progress组件进度值。用setInterval方法设置定时任务,每间隔一段时间(如20毫秒)均匀地改变Progress组件进度值(如每次加1),即可实现预期效果,详情请参见示例代码注释部分。
示例代码:
/** 进度条最小值 */
const PROGRESS_MIN = 0
/** 进度条最大值 */
const PROGRESS_MAX = 100
@Entry
@Component
struct ProgressAnim {
/** 进度条当前值 */
@State progressValue: number = PROGRESS_MIN
/** interval操作的标识符 */
@State intervalId: number | null = null
aboutToAppear(): void {
// 进入界面时即启动进度条动画
this.startAnim()
}
build() {
Column({ space: 15 }) {
Progress({
value: this.progressValue, // 进度条当前进度值
total: PROGRESS_MAX, // 进度条总长
type: ProgressType.Ring, // 进度条类型,分为Linear线性样式、ScaleRing环形有刻度样式、Ring环形无刻度样式、Eclipse圆形样式、Capsule胶囊样式
})
.style({
strokeWidth: 10, // 进度条宽度,默认4vp
enableSmoothEffect: true // 进度平滑动效的开关。开启平滑动效后设置进度,进度会从当前值渐变至设定值,否则进度从当前值突变至设定值,默认值true
})
.width(100) // 进度条组件宽度
.color('# A97CF9') // 进度条前景色
.backgroundColor(Color.White) // 进度条背景色
Button('开始动画')
.onClick(() => {
this.startAnim()
})
Button('结束动画')
.onClick(() => {
// 取消先前通过调用 setInterval() 设置的重复定时任务(进度条从最小值到最大值循环增加)
clearInterval(this.intervalId)
// 将intervalId重置为null,表示重复定时任务未启动
this.intervalId = null
// 进度值重置为最小值
this.progressValue = PROGRESS_MIN
})
}
.width('100%')
.padding({ top: 5 })
.backgroundColor(Color.Gray)
}
// 开启进度条动画
private startAnim() {
// intervalId为null时表示未启动interval
if (this.intervalId === null) {
this.intervalId = setInterval(() => {
// 使用setInterval() 方法重复执行以下代码片段,在每次调用之间具有固定的时间间隔20毫秒
// 每次进度值+1
this.progressValue++
// 当进度值达到最大值时,将进度值重置为最小值,循环往复
if (this.progressValue == PROGRESS_MAX) {
this.progressValue = PROGRESS_MIN
}
}, 20)
}
}
}
更多关于HarmonyOS鸿蒙Next中怎么解决Progress组件配合animateTo实现循环动画无反应问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS鸿蒙Next中怎么解决Progress组件配合animateTo实现循环动画无反应问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
使用animateTo
无法实现Progress
组件的循环动画,应改用setInterval
定时器控制进度值
示例代码如下:
@Entry
@Component
struct ProgressAnim {
@State progressValue: number = PROGRESS_MIN
@State intervalId: number | null = null
aboutToAppear(): void {
this.startAnim()
}
build() {
Column({ space: 15 }) {
Progress({
value: this.progressValue,
total: PROGRESS_MAX,
type: ProgressType.Ring,
})
.style({
strokeWidth: 10,
enableSmoothEffect: true
})
.width(100)
.color('#A97CF9')
.backgroundColor(Color.White)
Button('开始动画')
.onClick(() => {
this.startAnim()
})
Button('结束动画')
.onClick(() => {
clearInterval(this.intervalId)
this.intervalId = null
this.progressValue = PROGRESS_MIN
})
}
.width('100%')
.padding({ top: 5 })
.backgroundColor(Color.Gray)
}
private startAnim() {
if (this.intervalId === null) {
this.intervalId = setInterval(() => {
this.progressValue++
if (this.progressValue == PROGRESS_MAX) {
this.progressValue = PROGRESS_MIN
}
}, 20)
}
}
}