material-components/material-components-android · error · IllegalArgumentException

Slide distance must be positive. If attempting to reverse th

Error message

Slide distance must be positive. If attempting to reverse the direction of the slide, use setSlideEdge(int) instead.

What it means

SlideDistanceProvider (the engine behind MaterialSharedAxis and MaterialFadeThrough's slide) lets you override the translation distance via setSlideDistance(int px). A negative distance is rejected with IllegalArgumentException because the sign encodes direction, which must instead be chosen with setSlideEdge(int) (e.g., Gravity.START vs Gravity.END). Throwing here prevents transitions that slide the wrong way with an inverted easing feel.

Source

Thrown at lib/java/com/google/android/material/transition/platform/SlideDistanceProvider.java:100

   * @see #setSlideDistance(int)
   */
  @Px
  public int getSlideDistance() {
    return slideDistance;
  }

  /**
   * Set the distance this animator will translate its target.
   *
   * <p>By default, this value is set to -1 which indicates that the default slide distance,
   * R.dimen.mtrl_transition_shared_axis_slide_distance will be used. Setting the slide distance to
   * any other value will override this default.
   *
   * @throws IllegalArgumentException If {@code slideDistance} is negative.
   */
  public void setSlideDistance(@Px int slideDistance) {
    if (slideDistance < 0) {
      throw new IllegalArgumentException(
          "Slide distance must be positive. If attempting to reverse the direction of the slide,"
              + " use setSlideEdge(int) instead.");
    }
    this.slideDistance = slideDistance;
  }

  @Nullable
  @Override
  public Animator createAppear(@NonNull ViewGroup sceneRoot, @NonNull View view) {
    return createTranslationAppearAnimator(
        sceneRoot, view, slideEdge, getSlideDistanceOrDefault(view.getContext()));
  }

  @Nullable
  @Override
  public Animator createDisappear(@NonNull ViewGroup sceneRoot, @NonNull View view) {
    return createTranslationDisappearAnimator(
        sceneRoot, view, slideEdge, getSlideDistanceOrDefault(view.getContext()));

View on GitHub (pinned to ac7e18efee)

Solutions

  1. To reverse direction, use setSlideEdge with the opposite gravity: swap Gravity.START <-> Gravity.END (or LEFT <-> RIGHT, TOP <-> BOTTOM) and keep the distance positive.
  2. Sanitize computed distances before setting: slideProvider.setSlideDistance(Math.abs(distancePx));
  3. If the distance is resource-driven, make sure the resource is a positive dimen, not a signed calculation.
  4. Keep the default (-1 sentinel) if you only need the standard R.dimen.mtrl_transition_shared_axis_slide_distance.

Example fix

// before (want slide to come from the right)
provider.setSlideDistance(-distancePx); // throws
MaterialSharedAxis axis = new MaterialSharedAxis(context, attr, MaterialSharedAxis.X);

// after
provider.setSlideEdge(forward ? Gravity.START : Gravity.END);
provider.setSlideDistance(distancePx);
Defensive patterns

Strategy: validation

Validate before calling

// Only non-negative distances are legal; direction is chosen by the edge.
int safeSlideDistance(int distancePx) {
  return Math.abs(distancePx);
}
provider.setSlideDistance(safeSlideDistance(distancePx));

Type guard

static boolean isLegalSlideDistance(int distancePx) {
  return distancePx >= 0; // -1 is the internal 'use default' sentinel, not a user value
}

Try / catch

try {
  provider.setSlideDistance(distancePx);
} catch (IllegalArgumentException e) {
  if (e.getMessage() != null && e.getMessage().contains("Slide distance must be positive")) {
    provider.setSlideEdge(oppositeEdge(slideEdge)); // flip direction instead
    provider.setSlideDistance(Math.abs(distancePx));
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling setSlideDistance(-res.getDimensionPixelSize(...)); computing distance from a delta that can go negative (view1.left - view2.left); passing a signed dimension read from a layout that flips in RTL; mirroring sample code that negates the distance to reverse the animation.

Common situations: Developer wants the shared-axis slide to go the other way and negates the distance instead of switching the edge; distance derived from a signed offset in a parallax/scroll-linked animation; RTL layouts producing negative dimension deltas.

Related errors


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