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

ratio must be a float value between 0 and 1

Error message

ratio must be a float value between 0 and 1

What it means

BottomSheetBehavior.setHalfExpandedRatio(float) sets what fraction of the parent height the sheet occupies in STATE_HALF_EXPANDED. The value is annotated @FloatRange(from=0, to=1, fromInclusive=false, toInclusive=false) — it must be strictly between 0 and 1; 0.0f, 1.0f, negative values, and values above 1 all throw IllegalArgumentException.

Source

Thrown at lib/java/com/google/android/material/bottomsheet/BottomSheetBehavior.java:1168

  public int getPeekHeight() {
    return peekHeightAuto ? PEEK_HEIGHT_AUTO : peekHeight;
  }

  /**
   * Determines the height of the BottomSheet in the {@link #STATE_HALF_EXPANDED} state. The
   * material guidelines recommended a value of 0.5, which results in the sheet filling half of the
   * parent. The height of the BottomSheet will be smaller as this ratio is decreased and taller as
   * it is increased. The default value is 0.5.
   *
   * @param ratio a float between 0 and 1, representing the {@link #STATE_HALF_EXPANDED} ratio.
   * @attr ref
   *     com.google.android.material.R.styleable#BottomSheetBehavior_Layout_behavior_halfExpandedRatio
   */
  public void setHalfExpandedRatio(
      @FloatRange(from = 0.0f, to = 1.0f, fromInclusive = false, toInclusive = false) float ratio) {

    if ((ratio <= 0) || (ratio >= 1)) {
      throw new IllegalArgumentException("ratio must be a float value between 0 and 1");
    }
    this.halfExpandedRatio = ratio;
    // If sheet is already laid out, recalculate the half expanded offset based on new setting.
    // Otherwise, let onLayoutChild handle this later.
    if (viewRef != null) {
      calculateHalfExpandedOffset();
    }
  }

  /**
   * Gets the ratio for the height of the BottomSheet in the {@link #STATE_HALF_EXPANDED} state.
   *
   * @attr ref
   *     com.google.android.material.R.styleable#BottomSheetBehavior_Layout_behavior_halfExpandedRatio
   */
  @FloatRange(from = 0.0f, to = 1.0f)
  public float getHalfExpandedRatio() {
    return halfExpandedRatio;

View on GitHub (pinned to ac7e18efee)

Solutions

  1. Pass a value strictly inside (0, 1), e.g. the default 0.5f.
  2. Clamp computed values away from the endpoints: Math.min(Math.max(ratio, 0.01f), 0.99f).
  3. Validate persisted/remote values before applying them to the behavior.

Example fix

// before
behavior.setHalfExpandedRatio(sheetHeight / parentHeight); // 1.0 when full height

// after
float ratio = Math.min(Math.max(sheetHeight / (float) parentHeight, 0.01f), 0.99f);
behavior.setHalfExpandedRatio(ratio);
Defensive patterns

Strategy: validation

Validate before calling

float ratio = Math.min(Math.max(desiredRatio, Float.MIN_VALUE), 0.9999f);
behavior.setHalfExpandedRatio(ratio); // strictly within (0,1)

Prevention

When it happens

Trigger: Calling setHalfExpandedRatio(0f) or setHalfExpandedRatio(1f) exactly; deriving the ratio from a computation (sheetHeight / parentHeight) that evaluates to 0 or 1 on tiny or full-height content; loading the ratio from a config value that defaults to 0.

Common situations: Computing the ratio dynamically at runtime so edge-case layouts (0-height or full-height sheets) produce exactly 0 or 1; storing the ratio in remote config/backend with an unset 0 default; forgetting that both endpoints are exclusive.

Related errors


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