{"record":{"id":"1d9a0c7f2c288a9b","repo":"material-components/material-components-android","slug":"cannot-have-more-than-one-revealablelistitem-with","errorCode":null,"errorMessage":"Cannot have more than one RevealableListItem with the same absolute gravity.","messagePattern":"Cannot have more than one RevealableListItem with the same absolute gravity\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"lib/java/com/google/android/material/listitem/ListItemLayout.java","lineNumber":975,"sourceCode":"        || swipeToRevealLayoutRight instanceof RevealableListItem;\n  }\n\n  private void maybeSwapRevealLayoutsForGravity() {\n    boolean leftIsMisaligned =\n        swipeToRevealLayoutLeft != null && isRightAligned(swipeToRevealLayoutLeft);\n    boolean rightIsMisaligned =\n        swipeToRevealLayoutRight != null && !isRightAligned(swipeToRevealLayoutRight);\n\n    if (leftIsMisaligned && rightIsMisaligned) {\n      View temp = swipeToRevealLayoutLeft;\n      swipeToRevealLayoutLeft = swipeToRevealLayoutRight;\n      swipeToRevealLayoutRight = temp;\n      // If we swap, the offset should flip to keep the same active reveal layout.\n      revealViewOffset *= -1;\n    } else if (leftIsMisaligned) {\n      // If there is already an end gravity swipeToRevealLayout, we cannot replace it.\n      if (swipeToRevealLayoutRight != null) {\n        throw new IllegalStateException(\n            \"Cannot have more than one RevealableListItem with the same absolute gravity.\");\n      }\n      swipeToRevealLayoutRight = swipeToRevealLayoutLeft;\n      swipeToRevealLayoutLeft = null;\n      revealViewOffset *= -1;\n    } else if (rightIsMisaligned) {\n      // If there is already an start gravity swipeToRevealLayout, we cannot replace it.\n      if (swipeToRevealLayoutLeft != null) {\n        throw new IllegalStateException(\n            \"Cannot have more than one RevealableListItem with the same absolute gravity.\");\n      }\n      swipeToRevealLayoutLeft = swipeToRevealLayoutRight;\n      swipeToRevealLayoutRight = null;\n      revealViewOffset *= -1;\n    }\n  }\n\n  @Override","sourceCodeStart":957,"sourceCodeEnd":993,"githubUrl":"https://github.com/material-components/material-components-android/blob/ac7e18efeefb331850c561faf9ab8bf81d27ba68/lib/java/com/google/android/material/listitem/ListItemLayout.java#L957-L993","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"<!-- before: both reveal children effectively end-aligned -->\n<RevealLeft  layout_gravity=\"right\" .../>\n<RevealRight layout_gravity=\"end\" .../>\n\n<!-- after -->\n<RevealLeft  layout_gravity=\"start\" .../>\n<RevealRight layout_gravity=\"end\" .../>","handlingStrategy":"validation","validationCode":"View l = listItemLayout.findViewById(R.id.reveal_start);\nView r = listItemLayout.findViewById(R.id.reveal_end);\nif (l != null && r != null\n    && sameAbsoluteGravity((ListItemLayout.LayoutParams) l.getLayoutParams(),\n                           (ListItemLayout.LayoutParams) r.getLayoutParams())) {\n  throw new IllegalStateException(\"Both reveal children share absolute gravity\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["material-components","listitem","swipe","rtl","gravity"],"backgroundTag":null,"analyzedSha":"ac7e18efeefb331850c561faf9ab8bf81d27ba68","analyzedAt":"2026-08-14T15:35:35.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}