DEV Community

HarmonyOS
HarmonyOS

Posted on

How to solve the problem of the Progress component not responding when using animateTo to create a looping animation ?

Read the original article:How to solve the problem of the Progress component not responding when using animateTo to create a looping animation ?

How to solve the problem of the Progress component not responding when using animateTo to create a looping animation ?

Problem Description

Using the Progress component with animateTo to achieve a looping animation for the progress bar results in the animation not working and being unresponsive.

/** Minimum value of the progress bar */
const PROGRESS_MIN = 0
/** Maximum progress bar value */
const PROGRESS_MAX = 100

@Entry
@Component
struct ProgressAnim {
  /** Current value of the progress bar */
  @State progressValue: number = PROGRESS_MIN
  uiContext: UIContext | undefined = undefined;

  aboutToAppear() {
    this.uiContext = this.getUIContext();
    if (!this.uiContext) {
      console.warn("no uiContext");
      return;
    }
  }

  build() {
    Column({ space: 15 }) {
      Progress({
        value: this.progressValue, // Current progress value of the progress bar
        total: PROGRESS_MAX, // Total length of the progress bar
        type: ProgressType.Ring, // Progress bar types include Linear (linear style), ScaleRing (ring with scale style), Ring (ring without scale style), Eclipse (circular style), and Capsule (capsule style).
      })
        .style({
          strokeWidth: 10, // Progress bar width, default is 4vp.
          enableSmoothEffect: true // Switch for enabling or disabling the smooth progress effect. When the smooth effect is enabled, the progress will gradually transition from the current value to the set value; otherwise, it will abruptly change from the current value to the set value. Default value: true.
        })
        .width(100) // Progress bar component width
        .color('# A97CF9') // Progress bar foreground color
        .backgroundColor(Color.White) // Progress bar background color
      Button('Start Animation')
        .onClick(() => {
          this.uiContext?.animateTo({
            duration: 2000,
            iterations: -1, // Setting -1 indicates that the animation loops indefinitely.
          }, () => {
            this.progressValue = PROGRESS_MAX
          })
        })
    }
    .width('100%')
    .padding({ top: 5 })
    .backgroundColor(Color.Gray)
  }
}
Enter fullscreen mode Exit fullscreen mode

Background Knowledge

  • Progress: Displays loading/operation progress; styles include Capsule, Ring (with/without ticks), Circle, and custom shapes.
  • Explicit animation (animateTo): Inserts transition effects for state changes of component properties (e.g., size, color). Content values that are not animated properties (like a progress value that the component doesn’t animate via animateTo) jump to the final state.
  • Timer: setInterval() repeatedly invokes a function at fixed intervals and returns an ID that must be cleared with clearInterval().

Troubleshooting Process

  1. Implemented a Progress (Ring) and updated its value inside uiContext.animateTo({...}, () => { this.progressValue = 100 }) with iterations: -1.
  2. Observed that the progress animates from 0 → 100 only once; it does not loop as expected.
  3. Reasoned that animateTo targets view property transitions, not repeatedly driving the Progress value.
  4. Replaced animateTo with a timer-driven approach: use setInterval() to increment progressValue periodically and reset when reaching the maximum.

Analysis Conclusion

animateTo is suitable for component property transitions (e.g., size/opacity/color), not for looping a Progress value. A timer is required to continuously update the value.

Solution

Use setInterval() to drive progressValue from PROGRESS_MIN to PROGRESS_MAX and wrap around, producing a smooth, continuous loop (optionally enable enableSmoothEffect for eased transitions inside the Progress itself).

kbs--cf43b9ee2e6a43e8927669269cee261d-878ed.gif

Verification Result

  • With the timer-based approach, the Progress animates smoothly and loops indefinitely.
  • The “Start” button has no effect if the loop is already running; “Stop” halts the loop and resets to the minimum.

Related Documents or Links

  • Progress component guide (HarmonyOS/ArkTS):

https://developer.huawei.com/consumer/en/doc/harmonyos-guides/arkts-common-components-progress-indicator

  • UIContext.animateTo API:

https://developer.huawei.com/consumer/en/doc/harmonyos-references/development-intro-api

  • Timer APIs (setInterval, clearInterval):

https://developer.huawei.com/consumer/en/doc/harmonyos-references/js-apis-timer#setinterval

Written by Bunyamin Eymen Alagoz

Top comments (0)