material-components/material-components-android · error · UnsupportedOperationException
Only one SwipeableListItem view is allowed in a ListItemLayo
Error message
Only one SwipeableListItem view is allowed in a ListItemLayout.
What it means
ListItemLayout designates the first SwipeableListItem child as its swipeable content view (contentView). If another SwipeableListItem is added while contentView is already set, the layout cannot know which view to translate during swipes, so addView throws UnsupportedOperationException.
Source
Thrown at lib/java/com/google/android/material/listitem/ListItemLayout.java:260
if (isRightAligned(child)) {
if (swipeToRevealLayoutRight != null) {
throw new UnsupportedOperationException(
"Only one RevealableListItem with end gravity is supported.");
}
swipeToRevealLayoutRight = child;
} else {
if (swipeToRevealLayoutLeft != null) {
throw new UnsupportedOperationException(
"Only one RevealableListItem with start gravity is supported.");
}
swipeToRevealLayoutLeft = child;
}
// Start the reveal view at a desired width of 0
((RevealableListItem) child).setRevealedWidth(0);
// Make sure reveal view has lower elevation
child.setElevation(getElevation() - 1);
} else if (contentView != null && child instanceof SwipeableListItem) {
throw new UnsupportedOperationException(
"Only one SwipeableListItem view is allowed in a ListItemLayout.");
} else if (child instanceof SwipeableListItem) {
contentView = child;
}
}
@Override
public void onViewRemoved(View child) {
super.onViewRemoved(child);
if (child == swipeToRevealLayoutLeft) {
swipeToRevealLayoutLeft = null;
} else if (child == swipeToRevealLayoutRight) {
swipeToRevealLayoutRight = null;
} else if (contentView == child) {
contentView = null;
}
if (!swipeToRevealLayoutExists() || contentView == null) {View on GitHub (pinned to ac7e18efee)
Solutions
- Keep exactly one SwipeableListItem per ListItemLayout — it should be the main content view.
- Ensure custom content views implement SwipeableListItem only once at the top level; nested helpers should not implement the interface.
- When swapping content dynamically, remove the old content view before adding the new one.
Example fix
<!-- before -->
<ListItemLayout>
<SwipeableContentA .../>
<SwipeableContentB .../> <!-- throws: second SwipeableListItem -->
</ListItemLayout>
<!-- after: one swipeable content; second area is a plain view inside it -->
<ListItemLayout>
<SwipeableContent>
<PlainHeaderView .../><PlainBodyView .../>
</SwipeableContent>
<RevealItem layout_gravity="end" .../>
</ListItemLayout> Defensive patterns
Strategy: validation
Validate before calling
View oldContent = listItemLayout.findViewById(R.id.swipeable_content); if (oldContent != null) listItemLayout.removeView(oldContent); listItemLayout.addView(newSwipeableContent);
Prevention
- Design item layouts with exactly one SwipeableListItem as the content root.
- Make helper/inner views NOT implement SwipeableListItem.
- Review third-party custom views for unintended interface implementations.
When it happens
Trigger: Two views implementing SwipeableListItem in the same ListItemLayout (e.g. a custom content view plus a nested swipeable container); adding a second content view dynamically after the first bound one.
Common situations: Wrapping content in an extra swipeable container 'to be safe'; refactoring that nests SwipeableListItem implementations; third-party custom views implementing the interface unintentionally.
Related errors
- Only one RevealableListItem with end gravity is supported.
- Only one RevealableListItem with start gravity is supported.
- No RevealableListItem with gravity {}
- Invalid state to get swipe offset: {}
- revealView must be a child of ListItemLayout.
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/13c4c5b76da0a2aa.
Report an issue: GitHub.