文档管理中心
FAQ应用框架开发UI框架组件使用怎么解决Progress组件配合animateTo实现循环动画无反应问题

怎么解决Progress组件配合animateTo实现循环动画无反应问题

问题现象

使用Progress组件配合animateTo来实现进度条循环动画,动画效果失效无反应。

收起
自动换行
深色代码主题
复制
  1. /** 进度条最小值 */
  2. const PROGRESS_MIN1 = 0;
  3. /** 进度条最大值 */
  4. const PROGRESS_MAX1 = 100;
  5. @Entry
  6. @Component
  7. struct ProgressAnimWithProblem {
  8. /** 进度条当前值 */
  9. @State progressValue: number = PROGRESS_MIN1;
  10. uiContext: UIContext | undefined = undefined;
  11. aboutToAppear() {
  12. this.uiContext = this.getUIContext();
  13. if (!this.uiContext) {
  14. console.warn('no uiContext');
  15. return;
  16. };
  17. this.uiContext?.animateTo({
  18. duration: 2000,
  19. iterations: -1, // 设置-1表示动画无限循环
  20. }, () => {
  21. this.progressValue = PROGRESS_MAX1;
  22. });
  23. };
  24. build() {
  25. Column({ space: 15 }) {
  26. Progress({
  27. value: this.progressValue, // 进度条当前进度值
  28. total: PROGRESS_MAX1, // 进度条总长
  29. type: ProgressType.Ring, // 进度条类型,分为Linear线性样式、ScaleRing环形有刻度样式、Ring环形无刻度样式、Eclipse圆形样式、Capsule胶囊样式
  30. })
  31. .style({
  32. strokeWidth: 10, // 进度条宽度,默认4vp
  33. enableSmoothEffect: true // 进度平滑动效的开关。开启平滑动效后设置进度,进度会从当前值渐变至设定值,否则进度从当前值突变至设定值,默认值true
  34. })
  35. .width(100) // 进度条组件宽度
  36. .color('#0A59F7') // 进度条前景色
  37. .backgroundColor(Color.White); // 进度条背景色
  38. }
  39. .width('100%')
  40. .height('100%')
  41. .padding({ top: 5 })
  42. .justifyContent(FlexAlign.Center);
  43. };
  44. };

背景知识

  • 进度条(Progress):用于显示内容加载或操作处理等进度。可以有多种表现形式,官方提供胶囊型、环形有刻度、环形无刻度、圆形,且支持自定义图形样式。
  • 显式动画(animateTo):提供全局animateTo显式动画接口来指定由于闭包代码导致的状态变化插入过渡动效。同属性动画,布局类改变宽高的动画,内容都是直接到终点状态,例如文字、Canvas的内容等。
  • 定时器(Timer)setInterval()方法重复调用一个函数,在每次调用之间具有固定的时间延迟。此方法创建一个定时器并返回该定时器ID,删除该定时器需要手动调用clearInterval()

问题定位

animateTo适用于组件自身属性动画场景(如尺寸、颜色改变等),问题代码使用animateTo改变Progress组件的进度值,结果是进度条从0到100动画仅执行一次。可见不支持使用animateTo控制Progress组件进度条循环效果。

分析结论

animateTo适用于组件自身属性动画场景(如尺寸、颜色改变等),不支持使用animateTo控制Progress组件进度值变化来实现进度条循环效果。

修改建议

可以使用定时器来控制Progress组件进度值变化。用setInterval()方法创建定时任务,每间隔一段时间(如20毫秒)均匀地改变Progress组件进度值(如每次加1),即可实现预期效果。

收起
自动换行
深色代码主题
复制
  1. /** 进度条最小值 */
  2. const PROGRESS_MIN = 0;
  3. /** 进度条最大值 */
  4. const PROGRESS_MAX = 100;
  5. @Entry
  6. @Component
  7. struct ProgressAnim {
  8. /** 进度条当前值 */
  9. @State progressValue: number = PROGRESS_MIN;
  10. aboutToAppear(): void {
  11. // 进入界面时即启动进度条动画
  12. this.startAnim();
  13. };
  14. build() {
  15. Column({ space: 15 }) {
  16. Progress({
  17. value: this.progressValue, // 进度条当前进度值
  18. total: PROGRESS_MAX, // 进度条总长
  19. type: ProgressType.Ring, // 进度条类型,分为Linear线性样式、ScaleRing环形有刻度样式、Ring环形无刻度样式、Eclipse圆形样式、Capsule胶囊样式
  20. })
  21. .style({
  22. strokeWidth: 10, // 进度条宽度,默认4vp
  23. enableSmoothEffect: true // 进度平滑动效的开关。开启平滑动效后设置进度,进度会从当前值渐变至设定值,否则进度从当前值突变至设定值,默认值true
  24. })
  25. .width(100) // 进度条组件宽度
  26. .color('#0A59F7') // 进度条前景色
  27. .backgroundColor(Color.White); // 进度条背景色
  28. }
  29. .width('100%')
  30. .height('100%')
  31. .padding({ top: 5 })
  32. .justifyContent(FlexAlign.Center);
  33. };
  34. // 开启进度条动画
  35. private startAnim() {
  36. // intervalIdnull时表示未启动interval
  37. setInterval(() => {
  38. // 使用setInterval()方法重复执行以下代码片段,在每次调用之间具有固定的时间间隔20毫秒
  39. // 每次进度值+1
  40. this.progressValue++;
  41. // 当进度值达到最大值时,将进度值重置为最小值,循环往复
  42. if (this.progressValue == PROGRESS_MAX) {
  43. this.progressValue = PROGRESS_MIN;
  44. };
  45. }, 20);
  46. };
  47. };
在 FAQ 中进行搜索
请输入您想要搜索的关键词