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

customBadgeParent must be a FrameLayout

Error message

customBadgeParent must be a FrameLayout

What it means

The deprecated BadgeDrawable.updateBadgeCoordinates(View, ViewGroup) requires the custom badge parent to be a FrameLayout, because the badge is set as that parent's foreground and its center coordinates are computed against the parent's bounds. Any non-FrameLayout argument (including null) throws IllegalArgumentException. Use the non-deprecated overload taking a FrameLayout, or updateBadgeCoordinates(View).

Source

Thrown at lib/java/com/google/android/material/badge/BadgeDrawable.java:373

    restoreState();
  }

  /**
   * Calculates and updates this badge's center coordinates based on its anchor's bounds. Internally
   * also updates this {@code BadgeDrawable BadgeDrawable's} bounds, because they are dependent on
   * the center coordinates. For pre API-18, coordinates will be calculated relative to {@code
   * customBadgeParent} because the {@code BadgeDrawable} will be set as the parent's foreground.
   *
   * @param anchorView This badge's anchor.
   * @param customBadgeParent An optional parent view that will set this {@code BadgeDrawable} as
   *     its foreground.
   * @deprecated use {@link BadgeDrawable#updateBadgeCoordinates(View, FrameLayout)} instead.
   */
  @Deprecated
  public void updateBadgeCoordinates(
      @NonNull View anchorView, @Nullable ViewGroup customBadgeParent) {
    if (!(customBadgeParent instanceof FrameLayout)) {
      throw new IllegalArgumentException("customBadgeParent must be a FrameLayout");
    }
    updateBadgeCoordinates(anchorView, (FrameLayout) customBadgeParent);
  }

  /**
   * Calculates and updates this badge's center coordinates based on its anchor's bounds. Internally
   * also updates this {@code BadgeDrawable BadgeDrawable's} bounds, because they are dependent on
   * the center coordinates.
   *
   * @param anchorView This badge's anchor.
   */
  public void updateBadgeCoordinates(@NonNull View anchorView) {
    updateBadgeCoordinates(anchorView, null);
  }

  /**
   * Calculates and updates this badge's center coordinates based on its anchor's bounds. Internally
   * also updates this {@code BadgeDrawable BadgeDrawable's} bounds, because they are dependent on

View on GitHub (pinned to ac7e18efee)

Solutions

  1. Switch to the non-deprecated updateBadgeCoordinates(View anchorView) when no custom parent is needed.
  2. If a custom parent is required, pass a FrameLayout (e.g. wrap the anchor in one) or call the FrameLayout-typed overload updateBadgeCoordinates(View, FrameLayout).
  3. Never pass null as customBadgeParent to the deprecated overload — it throws; use the single-arg overload instead.

Example fix

// before (deprecated, throws for non-FrameLayout or null)
badgeDrawable.updateBadgeCoordinates(anchor, null);

// after
badgeDrawable.updateBadgeCoordinates(anchor);
// or, with a custom parent:
badgeDrawable.updateBadgeCoordinates(anchor, frameLayoutParent);
Defensive patterns

Strategy: type-guard

Type guard

if (customBadgeParent instanceof FrameLayout) {
  badge.updateBadgeCoordinates(anchor, (FrameLayout) customBadgeParent);
} else {
  badge.updateBadgeCoordinates(anchor); // no custom parent
}

Prevention

When it happens

Trigger: Calling the deprecated updateBadgeCoordinates(anchorView, customBadgeParent) where customBadgeParent is null (null fails the instanceof check), a LinearLayout, RelativeLayout, or any other non-FrameLayout ViewGroup.

Common situations: Migrating older badge code that passed an arbitrary parent view; passing null intending 'no custom parent' (null is rejected by this overload); wrapping the anchor in a ConstraintLayout and handing that in as the custom parent.

Related errors


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