material-components/material-components-android · error · IllegalArgumentException
ListItemLayout must have a SwipeableListItem child and a Rev
Error message
ListItemLayout must have a SwipeableListItem child and a RevealableListItem child to be swiped.
What it means
setSwipeState requires the ListItemLayout to be structurally complete before it can animate swipes: it must contain a SwipeableListItem content child (contentView) and at least one RevealableListItem. If either is missing there is nothing to swipe or reveal, so the method throws IllegalArgumentException telling you which children are required.
Source
Thrown at lib/java/com/google/android/material/listitem/ListItemLayout.java:919
}
/**
* Sets the state to swipe the {@link SwipeableListItem} child to.
*
* @param swipeState The state to swipe to. This must be one of {@link
* SwipeableListItem#STATE_CLOSED}, {@link SwipeableListItem#STATE_OPEN}, or {@link
* SwipeableListItem#STATE_SWIPE_PRIMARY_ACTION}
* @param revealGravity The gravity of the {@link RevealableListItem} to reveal when swiping.
* @param animate Whether to animate to the given swipe state.
*/
public void setSwipeState(
@StableSwipeState int swipeState, @RevealGravity int revealGravity, boolean animate) {
if (swipeState != STATE_CLOSED
&& swipeState != STATE_OPEN
&& swipeState != STATE_SWIPE_PRIMARY_ACTION) {
throw new IllegalArgumentException("Invalid swipe state: " + swipeState);
} else if (!(contentView instanceof SwipeableListItem) || !swipeToRevealLayoutExists()) {
throw new IllegalArgumentException(
"ListItemLayout must have a SwipeableListItem child and a RevealableListItem child to be"
+ " swiped.");
} else if (swipeState != STATE_CLOSED && !swipeToRevealLayoutExistsForGravity(revealGravity)) {
throw new IllegalArgumentException(
"No RevealableListItem is defined for the given gravity: " + revealGravity);
}
Runnable runnable =
() -> {
if (!animate) {
if (viewDragHelper != null) {
viewDragHelper.abort();
}
int finalLeft = getOffsetForSwipeState(swipeState, revealGravity);
contentView.offsetLeftAndRight(finalLeft - contentView.getLeft());
updateSwipeProgress(finalLeft);
setSwipeStateInternal(swipeState, revealGravity);
} else {View on GitHub (pinned to ac7e18efee)
Solutions
- Ensure the ListItemLayout XML (or dynamic construction) always includes one SwipeableListItem and at least one RevealableListItem before calling setSwipeState.
- Delay state restoration until after bind/layout: use itemView.post { ... } or do it in onBindViewHolder once children exist.
- To hide a reveal view temporarily, set visibility=GONE instead of removing it from the layout.
Example fix
// before
init { listItemLayout.setSwipeState(STATE_OPEN, gravity, false) } // children not inflated yet
// after
listItemLayout.post {
listItemLayout.setSwipeState(STATE_OPEN, gravity, false); // children attached
}; Defensive patterns
Strategy: validation
Validate before calling
boolean hasContent = listItemLayout.findViewById(R.id.swipeable_content) != null;
boolean hasReveal = listItemLayout.findViewById(R.id.reveal_end) != null
|| listItemLayout.findViewById(R.id.reveal_start) != null;
if (hasContent && hasReveal) listItemLayout.setSwipeState(state, gravity, animate); Prevention
- Restore swipe state after inflation/bind (itemView.post or onBindViewHolder), never in constructors.
- Hide reveal children with GONE rather than removing them.
- Structure item layouts to always contain the required children.
When it happens
Trigger: Calling setSwipeState before the layout is inflated with its children (e.g. in the constructor of a custom view or too early in a fragment lifecycle); a layout XML missing the reveal container; children removed dynamically leaving the layout incomplete.
Common situations: Restoring a saved swipe state in onViewStateRestored before the RecyclerView binds; conditionally hiding the reveal view via removeView instead of GONE; partial layouts during preview/edit-time inflation.
Related errors
- 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
- No RevealableListItem with gravity {}
- Invalid state to get swipe offset: {}
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/3b86a2c67131639f.
Report an issue: GitHub.