material-components/material-components-android · error · IllegalArgumentException
iconGravity cannot have the same alignment as secondaryIconG
Error message
iconGravity cannot have the same alignment as secondaryIconGravity
What it means
MaterialButton supports an optional secondary icon (e.g. for dropdown/chevron usage). The primary iconGravity and secondaryIconGravity must not resolve to the same alignment (start/end/top) when both icons are set, otherwise the two drawables would be stacked in the same compound-drawable slot. validateIconGravity enforces this with IllegalArgumentException whenever both icons exist and areIconsGravitySameAlignment() is true.
Source
Thrown at lib/java/com/google/android/material/button/MaterialButton.java:1258
boolean hasIconChanged =
(isIconStart() && drawableStart != icon)
|| (isIconEnd() && drawableEnd != icon)
|| (isIconTop() && drawableTop != icon);
// Force icon update if needsIconReset otherwise updated it only if icon has changed.
if (needsIconReset || hasIconChanged) {
if (isIconStart()) {
setCompoundDrawablesRelative(icon, getUpdatedIconFor(1), getUpdatedIconFor(2), null);
} else if (isIconEnd()) {
setCompoundDrawablesRelative(getUpdatedIconFor(0), getUpdatedIconFor(1), icon, null);
} else if (isIconTop()) {
setCompoundDrawablesRelative(getUpdatedIconFor(0), icon, getUpdatedIconFor(2), null);
}
}
}
private void validateIconGravity() {
if (icon != null && secondaryIcon != null && areIconsGravitySameAlignment()) {
throw new IllegalArgumentException(
"iconGravity cannot have the same alignment as secondaryIconGravity");
}
}
private boolean areIconsGravitySameAlignment() {
return (isIconStart() && isSecondaryIconStart())
|| (isIconEnd() && isSecondaryIconEnd())
|| (isIconTop() && isSecondaryIconTop());
}
@Nullable
private Drawable getUpdatedIconFor(int position) {
switch (position) {
case 0: // start
return (secondaryIcon != null && isSecondaryIconStart()) ? secondaryIcon : null;
case 1: // top
return (secondaryIcon != null && isSecondaryIconTop()) ? secondaryIcon : null;
case 2: // endView on GitHub (pinned to ac7e18efee)
Solutions
- Give the two gravities different alignments, e.g. iconGravity="start" with secondaryIconGravity="end" (the typical icon + chevron pattern).
- If only one icon is needed, remove the secondary icon (unset app:secondaryIcon / secondaryIcon null) so validation passes regardless of gravity values.
- When setting gravities programmatically, keep a mapping/constant pair that is guaranteed distinct.
Example fix
<!-- before -->
<com.google.android.material.button.MaterialButton
app:icon="@drawable/ic_send"
app:iconGravity="start"
app:secondaryIcon="@drawable/ic_chevron_down"
app:secondaryIconGravity="start" ... /> <!-- throws -->
<!-- after -->
<com.google.android.material.button.MaterialButton
app:icon="@drawable/ic_send"
app:iconGravity="start"
app:secondaryIcon="@drawable/ic_chevron_down"
app:secondaryIconGravity="end" ... /> Defensive patterns
Strategy: validation
Validate before calling
// Ensure the gravities differ whenever both icons are present
if (icon != null && secondaryIcon != null) {
android.util.Log.d(TAG, "primary=" + iconGravity + " secondary=" + secondaryIconGravity);
// require: not (start&start), (end&end), or (top&top)
} Type guard
private static boolean gravitiesConflict(int primaryGravity, int secondaryGravity) {
return primaryGravity == secondaryGravity; // same start/end/top alignment
}
// usage: if (!gravitiesConflict(iconGravity, secondaryIconGravity)) button.setSecondaryIcon(chevron); Prevention
- Use distinct alignments (e.g. primary=start, secondary=end) in shared styles.
- Only set a secondary icon when the gravity attributes are guaranteed different.
When it happens
Trigger: Setting both icon and secondaryIcon on the same MaterialButton with app:iconGravity and app:secondaryIconGravity both resolving to start, end, or top; changing gravity attributes in XML or calling the gravity setters so both align identically.
Common situations: Adding a secondary icon (e.g. a chevron) to an existing button that already has iconGravity="start" and copying the same value for secondaryIconGravity; configuring gravity from a shared style/theme so both attributes inherit the same alignment; programmatically toggling gravities at runtime without keeping them distinct.
Related errors
- iconSize cannot be less than 0
- AppBarLayout is always vertical and does not support horizon
- Invalid view edge position value:
- Email %d does not exist.
- Color names need to be at least four and correspond to attri
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/bcc4466155a63fcb.
Report an issue: GitHub.