{"record":{"id":"68d80505dc55a1d1","repo":"material-components/material-components-android","slug":"no-revealablelistitem-is-defined-for-the-given-gra","errorCode":null,"errorMessage":"No RevealableListItem is defined for the given gravity: {}","messagePattern":"No RevealableListItem is defined for the given gravity: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"lib/java/com/google/android/material/listitem/ListItemLayout.java","lineNumber":923,"sourceCode":"   *\n   * @param swipeState The state to swipe to. This must be one of {@link\n   *     SwipeableListItem#STATE_CLOSED}, {@link SwipeableListItem#STATE_OPEN}, or {@link\n   *     SwipeableListItem#STATE_SWIPE_PRIMARY_ACTION}\n   * @param revealGravity The gravity of the {@link RevealableListItem} to reveal when swiping.\n   * @param animate Whether to animate to the given swipe state.\n   */\n  public void setSwipeState(\n      @StableSwipeState int swipeState, @RevealGravity int revealGravity, boolean animate) {\n    if (swipeState != STATE_CLOSED\n        && swipeState != STATE_OPEN\n        && swipeState != STATE_SWIPE_PRIMARY_ACTION) {\n      throw new IllegalArgumentException(\"Invalid swipe state: \" + swipeState);\n    } else if (!(contentView instanceof SwipeableListItem) || !swipeToRevealLayoutExists()) {\n      throw new IllegalArgumentException(\n          \"ListItemLayout must have a SwipeableListItem child and a RevealableListItem child to be\"\n              + \" swiped.\");\n    } else if (swipeState != STATE_CLOSED && !swipeToRevealLayoutExistsForGravity(revealGravity)) {\n      throw new IllegalArgumentException(\n          \"No RevealableListItem is defined for the given gravity: \" + revealGravity);\n    }\n\n    Runnable runnable =\n        () -> {\n          if (!animate) {\n            if (viewDragHelper != null) {\n              viewDragHelper.abort();\n            }\n            int finalLeft = getOffsetForSwipeState(swipeState, revealGravity);\n            contentView.offsetLeftAndRight(finalLeft - contentView.getLeft());\n            updateSwipeProgress(finalLeft);\n            setSwipeStateInternal(swipeState, revealGravity);\n          } else {\n            startSettling(contentView, swipeState, revealGravity);\n          }\n        };\n    if (isLaidOut()) {","sourceCodeStart":905,"sourceCodeEnd":941,"githubUrl":"https://github.com/material-components/material-components-android/blob/ac7e18efeefb331850c561faf9ab8bf81d27ba68/lib/java/com/google/android/material/listitem/ListItemLayout.java#L905-L941","documentation":"Even when the layout is structurally valid, setSwipeState(STATE_OPEN or STATE_SWIPE_PRIMARY_ACTION, revealGravity, ...) needs a RevealableListItem registered for that specific gravity. If swiping toward the given gravity has no reveal view (e.g. only an end reveal exists but start gravity is requested), it throws IllegalArgumentException with the gravity value.","triggerScenarios":"setSwipeState(STATE_OPEN, REVEAL_GRAVITY_START, true) when the layout only contains an end-gravity RevealableListItem; hardcoding a gravity while the XML defines the other side; RTL conversions flipping which side is populated.","commonSituations":"Direction-dependent swipe actions (open = start reveal, action = end reveal) where one side was omitted from the layout; reusable list-item layouts used for items that only need one direction.","solutions":["Check the side you need exists: only call with a gravity whose reveal child is present, or use swipeToRevealLayoutExistsForGravity-equivalent checks (the view-based overload with a child of that layout).","Add RevealableListItem children for both gravities when your UX can swipe both ways.","Derive the gravity from the actual reveal view's LayoutParams instead of hardcoding."],"exampleFix":"// before\nlistItemLayout.setSwipeState(STATE_OPEN, ListItemLayout.REVEAL_GRAVITY_START, true);\n// only end reveal exists -> throws\n\n// after\nif (startReveal != null) {\n  listItemLayout.setSwipeState(STATE_OPEN, ListItemLayout.REVEAL_GRAVITY_START, true);\n} else {\n  listItemLayout.setSwipeState(STATE_OPEN, ListItemLayout.REVEAL_GRAVITY_END, true);\n}","handlingStrategy":"validation","validationCode":"View startReveal = listItemLayout.findViewById(R.id.reveal_start);\nView endReveal = listItemLayout.findViewById(R.id.reveal_end);\nint gravity = (startReveal != null) ? ListItemLayout.REVEAL_GRAVITY_START : ListItemLayout.REVEAL_GRAVITY_END;\nif (startReveal != null || endReveal != null) {\n  listItemLayout.setSwipeState(state, gravity, animate);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Query which reveal side exists before requesting a non-closed state for a gravity.","Define both reveal children when the UX swipes both directions.","Use start/end gravities consistently so RTL does not surprise you."],"tags":["material-components","listitem","swipe","gravity"],"backgroundTag":null,"analyzedSha":"ac7e18efeefb331850c561faf9ab8bf81d27ba68","analyzedAt":"2026-08-14T15:35:35.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}