SplitButton in Jetpack Compose
A split button pairs a main action (“Send”, “Save”) with a menu of related actions. The trailing
half is a toggle. While it’s checked, rotate the arrow and show your DropdownMenu.
@Composablefun SaveSplitButton(arrowDown: ImageVector, onSave: () -> Unit, onMenu: (Boolean) -> Unit) { var menuOpen by rememberSaveable { mutableStateOf(false) } SplitButtonLayout( leadingButton = { SplitButtonDefaults.LeadingButton(onClick = onSave) { Text("Save") } }, trailingButton = { SplitButtonDefaults.TrailingButton( checked = menuOpen, onCheckedChange = { menuOpen = it; onMenu(it) }, modifier = Modifier.semantics { stateDescription = if (menuOpen) "Expanded" else "Collapsed" }, ) { val rotation by animateFloatAsState(if (menuOpen) 180f else 0f, label = "arrow") Icon( arrowDown, contentDescription = "More save options", modifier = Modifier .size(SplitButtonDefaults.TrailingIconSize) .graphicsLayer { rotationZ = rotation }, ) } }, )}Variants come in matching pairs: LeadingButton/TrailingButton (filled), TonalLeadingButton/TonalTrailingButton,
ElevatedLeadingButton/ElevatedTrailingButton and OutlinedLeadingButton/OutlinedTrailingButton. Don’t mix them.
Accessibility
Section titled “Accessibility”The trailing button is icon-only. Give it a content description (“More save options”) and a
stateDescription of Expanded/Collapsed.
Related: buttons · floating toolbar
Want your agent to get this right every time? Install the skill. If this page helped,star the repo on GitHub.
Built by Sanikant. Set in Google Sans Flex (SIL Open Font License), icons from Material Symbols (Apache 2.0). Material Design is a Google trademark; this project is not affiliated with Google.