material-components/material-components-android · error · IllegalStateException
Cannot have more than one RevealableListItem with the same a
Error message
Cannot have more than one RevealableListItem with the same absolute gravity.
What it means
After layout, maybeSwapRevealLayoutsForGravity() re-classifies the two registered reveal children by absolute gravity (swapping their left/right slots when their declared gravity disagrees with actual alignment). If the left-aligned reveal view is actually misaligned to the right but an end-gravity reveal view is already registered, moving it would create two end-gravity views — an impossible state — so it throws IllegalStateException (first branch, leftIsMisaligned).
Source
Thrown at lib/java/com/google/android/material/listitem/ListItemLayout.java:975
|| swipeToRevealLayoutRight instanceof RevealableListItem;
}
private void maybeSwapRevealLayoutsForGravity() {
boolean leftIsMisaligned =
swipeToRevealLayoutLeft != null && isRightAligned(swipeToRevealLayoutLeft);
boolean rightIsMisaligned =
swipeToRevealLayoutRight != null && !isRightAligned(swipeToRevealLayoutRight);
if (leftIsMisaligned && rightIsMisaligned) {
View temp = swipeToRevealLayoutLeft;
swipeToRevealLayoutLeft = swipeToRevealLayoutRight;
swipeToRevealLayoutRight = temp;
// If we swap, the offset should flip to keep the same active reveal layout.
revealViewOffset *= -1;
} else if (leftIsMisaligned) {
// If there is already an end gravity swipeToRevealLayout, we cannot replace it.
if (swipeToRevealLayoutRight != null) {
throw new IllegalStateException(
"Cannot have more than one RevealableListItem with the same absolute gravity.");
}
swipeToRevealLayoutRight = swipeToRevealLayoutLeft;
swipeToRevealLayoutLeft = null;
revealViewOffset *= -1;
} else if (rightIsMisaligned) {
// If there is already an start gravity swipeToRevealLayout, we cannot replace it.
if (swipeToRevealLayoutLeft != null) {
throw new IllegalStateException(
"Cannot have more than one RevealableListItem with the same absolute gravity.");
}
swipeToRevealLayoutLeft = swipeToRevealLayoutRight;
swipeToRevealLayoutRight = null;
revealViewOffset *= -1;
}
}
@OverrideView on GitHub (pinned to ac7e18efee)
Solutions
- Give each RevealableListItem a layout_gravity that matches its intended side: one start, one end — never both the same.
- Use start/end (not left/right) gravities so RTL resolution stays consistent with the library's expectation.
- Avoid overriding onLayout/placement of reveal children; let ListItemLayout position them.
Example fix
<!-- before: both reveal children effectively end-aligned --> <RevealLeft layout_gravity="right" .../> <RevealRight layout_gravity="end" .../> <!-- after --> <RevealLeft layout_gravity="start" .../> <RevealRight layout_gravity="end" .../>
Defensive patterns
Strategy: validation
Validate before calling
View l = listItemLayout.findViewById(R.id.reveal_start);
View r = listItemLayout.findViewById(R.id.reveal_end);
if (l != null && r != null
&& sameAbsoluteGravity((ListItemLayout.LayoutParams) l.getLayoutParams(),
(ListItemLayout.LayoutParams) r.getLayoutParams())) {
throw new IllegalStateException("Both reveal children share absolute gravity");
} Prevention
- Use exactly one start and one end gravity on reveal children.
- Prefer start/end attributes over left/right for RTL safety.
- Test list items under RTL pseudolocales in CI.
When it happens
Trigger: A ListItemLayout with two RevealableListItem children whose layout_gravity values and actual layout alignment conflict (e.g. both effectively end-aligned after layout/RTL resolution); layout direction (RTL locale) changing between inflation and layout.
Common situations: Switching locale to RTL at runtime; hand-authored XML where start/end gravities on the two reveal children do not match their positions; custom onLayout interfering with child placement.
Related errors
- No RevealableListItem with gravity {}
- No RevealableListItem is defined for the given gravity: {}
- Only one RevealableListItem with end gravity is supported.
- Only one RevealableListItem with start gravity is supported.
- Only one SwipeableListItem view is allowed in a ListItemLayo
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/1d9a0c7f2c288a9b.
Report an issue: GitHub.