material-components/material-components-android · error · IllegalStateException

Cannot change indeterminate animation type while the progres

Error message

Cannot change indeterminate animation type while the progress indicator is show in indeterminate mode.

What it means

Thrown by LinearProgressIndicator.setIndeterminateAnimationType() when the indicator is currently visible to the user AND running in indeterminate mode. The library forbids swapping the animator delegate (disjoint <-> contiguous) mid-animation because the running indeterminate animator cannot be safely replaced while drawn. The guard is an explicit IllegalStateException before any state is mutated.

Source

Thrown at lib/java/com/google/android/material/progressindicator/LinearProgressIndicator.java:306

  public int getIndeterminateAnimationType() {
    return spec.indeterminateAnimationType;
  }

  /**
   * Sets the type of indeterminate animation.
   *
   * @param indeterminateAnimationType The new type of indeterminate animation.
   * @see #getIndeterminateAnimationType()
   * @attr ref
   *     com.google.android.material.progressindicator.R.styleable#LinearProgressIndicator_indeterminateAnimationType
   */
  public void setIndeterminateAnimationType(
      @IndeterminateAnimationType int indeterminateAnimationType) {
    if (spec.indeterminateAnimationType == indeterminateAnimationType) {
      return;
    }
    if (visibleToUser() && isIndeterminate()) {
      throw new IllegalStateException(
          "Cannot change indeterminate animation type while the progress indicator is show in"
              + " indeterminate mode.");
    }
    spec.indeterminateAnimationType = indeterminateAnimationType;
    spec.validateSpec();
    if (indeterminateAnimationType == INDETERMINATE_ANIMATION_TYPE_CONTIGUOUS) {
      getIndeterminateDrawable()
          .setAnimatorDelegate(new LinearIndeterminateContiguousAnimatorDelegate(spec));
    } else {
      getIndeterminateDrawable()
          .setAnimatorDelegate(new LinearIndeterminateDisjointAnimatorDelegate(getContext(), spec));
    }
    registerSwitchIndeterminateModeCallback();
    invalidate();
  }

  /**
   * Returns the indicator animating direction used in this progress indicator.

View on GitHub (pinned to ac7e18efee)

Solutions

  1. Switch to determinate mode first: call setIndeterminate(false) (or hide the indicator) before setIndeterminateAnimationType(...), then setIndeterminate(true) again if needed.
  2. Only call setIndeterminateAnimationType() before the indicator becomes visible — e.g. in XML via app:indeterminateAnimationType or right after inflation while detached/hidden.
  3. Wrap the call with a guard: if (!indicator.isIndeterminate() || !indicator.isShown()) { indicator.setIndeterminateAnimationType(type); }
  4. If restoring state, apply the saved animation type before the view is attached or before the first call to setIndeterminate(true).

Example fix

// before
indicator.setIndeterminateAnimationType(
    LinearProgressIndicator.INDETERMINATE_ANIMATION_TYPE_CONTIGUOUS); // crashes if visible+indeterminate

// after
indicator.setIndeterminate(false);
indicator.setIndeterminateAnimationType(
    LinearProgressIndicator.INDETERMINATE_ANIMATION_TYPE_CONTIGUOUS);
indicator.setIndeterminate(true);
Defensive patterns

Strategy: validation

Validate before calling

boolean canSwitchType(LinearProgressIndicator indicator) {
  return !indicator.isIndeterminate() || !indicator.isShown();
}

Try / catch

try { indicator.setIndeterminateAnimationType(type); } catch (IllegalStateException e) { Log.w(TAG, "Animation type switched while animating; retry after hiding", e); indicator.hide(); indicator.setIndeterminateAnimationType(type); indicator.show(); }

Prevention

When it happens

Trigger: Calling setIndeterminateAnimationType(LinearProgressIndicator.INDETERMINATE_ANIMATION_TYPE_CONTIGUOUS) (or _DISJOINT) while the indicator is attached, visible, and isIndeterminate() returns true — e.g. toggling animation type from a button click while the bar is animating.

Common situations: A settings screen lets users switch between contiguous and disjoint indeterminate styles; a fragment restores a visible indeterminate indicator and then applies a stored animation-type preference in onStart(); calling the setter unconditionally in onResume() on an already-animating bar.

Related errors


AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14). Data as JSON: /api/errors/f6d306d48778a023. Report an issue: GitHub.