SplitButton
Functions summary
Unit |
@ComposableA |
Cmn
|
Functions
SplitButton
@Composable
fun SplitButton(
leadingButton: @Composable () -> Unit,
trailingButton: @Composable () -> Unit,
modifier: Modifier = Modifier,
spacing: Dp = SplitButtonDefaults.Spacing
): Unit
A SplitButton lets users define a button group consisting of 2 buttons. The leading button performs a primary action, and the trailing button performs a secondary action that is contextually related to the primary action.
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material.icons.outlined.Edit import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.PlainTooltip import androidx.compose.material3.SplitButton import androidx.compose.material3.SplitButtonDefaults import androidx.compose.material3.Text import androidx.compose.material3.TooltipAnchorPosition import androidx.compose.material3.TooltipBox import androidx.compose.material3.TooltipDefaults import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.semantics.LiveRegionMode import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.liveRegion import androidx.compose.ui.semantics.paneTitle import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription var checked by remember { mutableStateOf(false) } SplitButton( leadingButton = { SplitButtonDefaults.LeadingButton(onClick = { /* Do Nothing */ }) { Icon( Icons.Filled.Edit, modifier = Modifier.size(SplitButtonDefaults.LeadingIconSize), contentDescription = "Localized description", ) Spacer(Modifier.size(ButtonDefaults.IconSpacing)) Text("My Button") } }, trailingButton = { val description = "Toggle Button" // Icon-only trailing button should have a tooltip for a11y. TooltipBox( positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above), tooltip = { PlainTooltip( modifier = Modifier.semantics { // TODO(b/496338253): Remove this modifier once bug where tooltip // text is not announced by a11y screen readers is resolved. liveRegion = LiveRegionMode.Assertive paneTitle = description } ) { Text(description) } }, state = rememberTooltipState(), ) { SplitButtonDefaults.TrailingButton( checked = checked, onCheckedChange = { checked = it }, modifier = Modifier.semantics { stateDescription = if (checked) "Expanded" else "Collapsed" contentDescription = description }, ) { val rotation: Float by animateFloatAsState( targetValue = if (checked) 180f else 0f, label = "Trailing Icon Rotation", ) Icon( Icons.Filled.KeyboardArrowDown, modifier = Modifier.size(SplitButtonDefaults.TrailingIconSize).graphicsLayer { this.rotationZ = rotation }, contentDescription = "Localized description", ) } } }, )
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material.icons.outlined.Edit import androidx.compose.material.icons.outlined.Email import androidx.compose.material.icons.outlined.Settings import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.PlainTooltip import androidx.compose.material3.SplitButton import androidx.compose.material3.SplitButtonDefaults import androidx.compose.material3.Text import androidx.compose.material3.TooltipAnchorPosition import androidx.compose.material3.TooltipBox import androidx.compose.material3.TooltipDefaults import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.semantics.LiveRegionMode import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.liveRegion import androidx.compose.ui.semantics.paneTitle import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription import androidx.compose.ui.text.style.TextAlign var checked by remember { mutableStateOf(false) } Box(modifier = Modifier.fillMaxSize().wrapContentSize()) { SplitButton( leadingButton = { SplitButtonDefaults.LeadingButton(onClick = { /* Do Nothing */ }) { Icon( Icons.Filled.Edit, modifier = Modifier.size(SplitButtonDefaults.LeadingIconSize), contentDescription = "Localized description", ) Spacer(Modifier.size(ButtonDefaults.IconSpacing)) Text("My Button") } }, trailingButton = { val description = "Toggle Button" // Icon-only trailing button should have a tooltip for a11y. TooltipBox( positionProvider = TooltipDefaults.rememberTooltipPositionProvider( TooltipAnchorPosition.Above ), tooltip = { PlainTooltip( modifier = Modifier.semantics { // TODO(b/496338253): Remove this modifier once bug where // tooltip text is not announced by a11y screen readers is // resolved. liveRegion = LiveRegionMode.Assertive paneTitle = description } ) { Text(description) } }, state = rememberTooltipState(), ) { SplitButtonDefaults.TrailingButton( checked = checked, onCheckedChange = { checked = it }, modifier = Modifier.semantics { stateDescription = if (checked) "Expanded" else "Collapsed" contentDescription = description }, ) { val rotation: Float by animateFloatAsState( targetValue = if (checked) 180f else 0f, label = "Trailing Icon Rotation", ) Icon( Icons.Filled.KeyboardArrowDown, modifier = Modifier.size(SplitButtonDefaults.TrailingIconSize).graphicsLayer { this.rotationZ = rotation }, contentDescription = "Localized description", ) } } }, ) DropdownMenu(expanded = checked, onDismissRequest = { checked = false }) { DropdownMenuItem( text = { Text("Edit") }, onClick = { /* Handle edit! */ }, leadingIcon = { Icon(Icons.Outlined.Edit, contentDescription = null) }, ) DropdownMenuItem( text = { Text("Settings") }, onClick = { /* Handle settings! */ }, leadingIcon = { Icon(Icons.Outlined.Settings, contentDescription = null) }, ) HorizontalDivider() DropdownMenuItem( text = { Text("Send Feedback") }, onClick = { /* Handle send feedback! */ }, leadingIcon = { Icon(Icons.Outlined.Email, contentDescription = null) }, trailingIcon = { Text("F11", textAlign = TextAlign.Center) }, ) } }
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material.icons.outlined.Edit import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.PlainTooltip import androidx.compose.material3.SplitButton import androidx.compose.material3.SplitButtonDefaults import androidx.compose.material3.Text import androidx.compose.material3.TooltipAnchorPosition import androidx.compose.material3.TooltipBox import androidx.compose.material3.TooltipDefaults import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.semantics.LiveRegionMode import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.liveRegion import androidx.compose.ui.semantics.paneTitle import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription var checked by remember { mutableStateOf(false) } SplitButton( leadingButton = { SplitButtonDefaults.TonalLeadingButton(onClick = { /* Do Nothing */ }) { Icon( Icons.Filled.Edit, modifier = Modifier.size(SplitButtonDefaults.LeadingIconSize), contentDescription = "Localized description", ) Spacer(Modifier.size(ButtonDefaults.IconSpacing)) Text("My Button") } }, trailingButton = { val description = "Toggle Button" // Icon-only trailing button should have a tooltip for a11y. TooltipBox( positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above), tooltip = { PlainTooltip( modifier = Modifier.semantics { // TODO(b/496338253): Remove this modifier once bug where tooltip // text is not announced by a11y screen readers is resolved. liveRegion = LiveRegionMode.Assertive paneTitle = description } ) { Text(description) } }, state = rememberTooltipState(), ) { SplitButtonDefaults.TonalTrailingButton( checked = checked, onCheckedChange = { checked = it }, modifier = Modifier.semantics { stateDescription = if (checked) "Expanded" else "Collapsed" contentDescription = description }, ) { val rotation: Float by animateFloatAsState( targetValue = if (checked) 180f else 0f, label = "Trailing Icon Rotation", ) Icon( Icons.Filled.KeyboardArrowDown, modifier = Modifier.size(SplitButtonDefaults.TrailingIconSize).graphicsLayer { this.rotationZ = rotation }, contentDescription = "Localized description", ) } } }, )
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material.icons.outlined.Edit import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.PlainTooltip import androidx.compose.material3.SplitButton import androidx.compose.material3.SplitButtonDefaults import androidx.compose.material3.Text import androidx.compose.material3.TooltipAnchorPosition import androidx.compose.material3.TooltipBox import androidx.compose.material3.TooltipDefaults import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.semantics.LiveRegionMode import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.liveRegion import androidx.compose.ui.semantics.paneTitle import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription var checked by remember { mutableStateOf(false) } SplitButton( leadingButton = { SplitButtonDefaults.ElevatedLeadingButton(onClick = { /* Do Nothing */ }) { Icon( Icons.Filled.Edit, modifier = Modifier.size(SplitButtonDefaults.LeadingIconSize), contentDescription = "Localized description", ) Spacer(Modifier.size(ButtonDefaults.IconSpacing)) Text("My Button") } }, trailingButton = { val description = "Toggle Button" // Icon-only trailing button should have a tooltip for a11y. TooltipBox( positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above), tooltip = { PlainTooltip( modifier = Modifier.semantics { // TODO(b/496338253): Remove this modifier once bug where tooltip // text is not announced by a11y screen readers is resolved. liveRegion = LiveRegionMode.Assertive paneTitle = description } ) { Text(description) } }, state = rememberTooltipState(), ) { SplitButtonDefaults.ElevatedTrailingButton( checked = checked, onCheckedChange = { checked = it }, modifier = Modifier.semantics { stateDescription = if (checked) "Expanded" else "Collapsed" contentDescription = description }, ) { val rotation: Float by animateFloatAsState( targetValue = if (checked) 180f else 0f, label = "Trailing Icon Rotation", ) Icon( Icons.Filled.KeyboardArrowDown, modifier = Modifier.size(SplitButtonDefaults.TrailingIconSize).graphicsLayer { this.rotationZ = rotation }, contentDescription = "Localized description", ) } } }, )
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material.icons.outlined.Edit import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.PlainTooltip import androidx.compose.material3.SplitButton import androidx.compose.material3.SplitButtonDefaults import androidx.compose.material3.Text import androidx.compose.material3.TooltipAnchorPosition import androidx.compose.material3.TooltipBox import androidx.compose.material3.TooltipDefaults import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.semantics.LiveRegionMode import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.liveRegion import androidx.compose.ui.semantics.paneTitle import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription var checked by remember { mutableStateOf(false) } SplitButton( leadingButton = { SplitButtonDefaults.OutlinedLeadingButton(onClick = { /* Do Nothing */ }) { Icon( Icons.Filled.Edit, modifier = Modifier.size(SplitButtonDefaults.LeadingIconSize), contentDescription = "Localized description", ) Spacer(Modifier.size(ButtonDefaults.IconSpacing)) Text("My Button") } }, trailingButton = { val description = "Toggle Button" // Icon-only trailing button should have a tooltip for a11y. TooltipBox( positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above), tooltip = { PlainTooltip( modifier = Modifier.semantics { // TODO(b/496338253): Remove this modifier once bug where tooltip // text is not announced by a11y screen readers is resolved. liveRegion = LiveRegionMode.Assertive paneTitle = description } ) { Text(description) } }, state = rememberTooltipState(), ) { SplitButtonDefaults.OutlinedTrailingButton( checked = checked, onCheckedChange = { checked = it }, modifier = Modifier.semantics { stateDescription = if (checked) "Expanded" else "Collapsed" contentDescription = description }, ) { val rotation: Float by animateFloatAsState( targetValue = if (checked) 180f else 0f, label = "Trailing Icon Rotation", ) Icon( Icons.Filled.KeyboardArrowDown, modifier = Modifier.size(SplitButtonDefaults.TrailingIconSize).graphicsLayer { this.rotationZ = rotation }, contentDescription = "Localized description", ) } } }, )
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material.icons.outlined.Edit import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.PlainTooltip import androidx.compose.material3.SplitButton import androidx.compose.material3.SplitButtonDefaults import androidx.compose.material3.Text import androidx.compose.material3.TooltipAnchorPosition import androidx.compose.material3.TooltipBox import androidx.compose.material3.TooltipDefaults import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.semantics.LiveRegionMode import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.liveRegion import androidx.compose.ui.semantics.paneTitle import androidx.compose.ui.semantics.semantics SplitButton( leadingButton = { SplitButtonDefaults.LeadingButton(onClick = { /* Do Nothing */ }) { Icon( Icons.Filled.Edit, modifier = Modifier.size(SplitButtonDefaults.LeadingIconSize), contentDescription = "Localized description", ) Spacer(Modifier.size(ButtonDefaults.IconSpacing)) Text("My Button") } }, trailingButton = { val description = "Toggle Button" // Icon-only trailing button should have a tooltip for a11y. TooltipBox( positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above), tooltip = { PlainTooltip( modifier = Modifier.semantics { // TODO(b/496338253): Remove this modifier once bug where tooltip // text is not announced by a11y screen readers is resolved. liveRegion = LiveRegionMode.Assertive paneTitle = description } ) { Text(description) } }, state = rememberTooltipState(), ) { SplitButtonDefaults.TrailingButton(onClick = { /* Do Nothing */ }) { Icon( Icons.Filled.KeyboardArrowDown, modifier = Modifier.size(SplitButtonDefaults.TrailingIconSize), contentDescription = description, ) } } }, )
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.PlainTooltip import androidx.compose.material3.SplitButton import androidx.compose.material3.SplitButtonDefaults import androidx.compose.material3.Text import androidx.compose.material3.TooltipAnchorPosition import androidx.compose.material3.TooltipBox import androidx.compose.material3.TooltipDefaults import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.semantics.LiveRegionMode import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.liveRegion import androidx.compose.ui.semantics.paneTitle import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription var checked by remember { mutableStateOf(false) } SplitButton( leadingButton = { SplitButtonDefaults.LeadingButton(onClick = { /* Do Nothing */ }) { Text("My Button") } }, trailingButton = { val description = "Toggle Button" // Icon-only trailing button should have a tooltip for a11y. TooltipBox( positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above), tooltip = { PlainTooltip( modifier = Modifier.semantics { // TODO(b/496338253): Remove this modifier once bug where tooltip // text is not announced by a11y screen readers is resolved. liveRegion = LiveRegionMode.Assertive paneTitle = description } ) { Text(description) } }, state = rememberTooltipState(), ) { SplitButtonDefaults.TrailingButton( checked = checked, onCheckedChange = { checked = it }, modifier = Modifier.semantics { stateDescription = if (checked) "Expanded" else "Collapsed" contentDescription = description }, ) { val rotation: Float by animateFloatAsState( targetValue = if (checked) 180f else 0f, label = "Trailing Icon Rotation", ) Icon( Icons.Filled.KeyboardArrowDown, modifier = Modifier.size(SplitButtonDefaults.TrailingIconSize).graphicsLayer { this.rotationZ = rotation }, contentDescription = "Localized description", ) } } }, )
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material.icons.outlined.Edit import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.PlainTooltip import androidx.compose.material3.SplitButton import androidx.compose.material3.SplitButtonDefaults import androidx.compose.material3.Text import androidx.compose.material3.TooltipAnchorPosition import androidx.compose.material3.TooltipBox import androidx.compose.material3.TooltipDefaults import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.semantics.LiveRegionMode import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.liveRegion import androidx.compose.ui.semantics.paneTitle import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription var checked by remember { mutableStateOf(false) } SplitButton( leadingButton = { val description = "Button" // Icon-only leading button should have a tooltip for a11y. TooltipBox( positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above), tooltip = { PlainTooltip( modifier = Modifier.semantics { // TODO(b/496338253): Remove this modifier once bug where tooltip // text is not announced by a11y screen readers is resolved. liveRegion = LiveRegionMode.Assertive paneTitle = description } ) { Text(description) } }, state = rememberTooltipState(), ) { SplitButtonDefaults.LeadingButton(onClick = { /* Do Nothing */ }) { Icon( Icons.Filled.Edit, contentDescription = description, Modifier.size(SplitButtonDefaults.LeadingIconSize), ) } } }, trailingButton = { val description = "Toggle Button" // Icon-only trailing button should have a tooltip for a11y. TooltipBox( positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above), tooltip = { PlainTooltip( modifier = Modifier.semantics { // TODO(b/496338253): Remove this modifier once bug where tooltip // text is not announced by a11y screen readers is resolved. liveRegion = LiveRegionMode.Assertive paneTitle = description } ) { Text(description) } }, state = rememberTooltipState(), ) { SplitButtonDefaults.TrailingButton( checked = checked, onCheckedChange = { checked = it }, modifier = Modifier.semantics { stateDescription = if (checked) "Expanded" else "Collapsed" contentDescription = description }, ) { val rotation: Float by animateFloatAsState( targetValue = if (checked) 180f else 0f, label = "Trailing Icon Rotation", ) Icon( Icons.Filled.KeyboardArrowDown, modifier = Modifier.size(SplitButtonDefaults.TrailingIconSize).graphicsLayer { this.rotationZ = rotation }, contentDescription = "Localized description", ) } } }, )
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material.icons.outlined.Edit import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.PlainTooltip import androidx.compose.material3.SplitButton import androidx.compose.material3.SplitButtonDefaults import androidx.compose.material3.Text import androidx.compose.material3.TooltipAnchorPosition import androidx.compose.material3.TooltipBox import androidx.compose.material3.TooltipDefaults import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.semantics.LiveRegionMode import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.liveRegion import androidx.compose.ui.semantics.paneTitle import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription var checked by remember { mutableStateOf(false) } val size = SplitButtonDefaults.ExtraSmallContainerHeight SplitButton( leadingButton = { SplitButtonDefaults.LeadingButton( onClick = { /* Do Nothing */ }, modifier = Modifier.heightIn(size), shapes = SplitButtonDefaults.leadingButtonShapesFor(size), contentPadding = SplitButtonDefaults.leadingButtonContentPaddingFor(size), ) { Icon( Icons.Filled.Edit, modifier = Modifier.size(SplitButtonDefaults.leadingButtonIconSizeFor(size)), contentDescription = "Localized description", ) Spacer(Modifier.size(ButtonDefaults.iconSpacingFor(size))) Text("Label", style = ButtonDefaults.textStyleFor(size)) } }, trailingButton = { val description = "Toggle Button" // Icon-only trailing button should have a tooltip for a11y. TooltipBox( positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above), tooltip = { PlainTooltip( modifier = Modifier.semantics { // TODO(b/496338253): Remove this modifier once bug where tooltip // text is not announced by a11y screen readers is resolved. liveRegion = LiveRegionMode.Assertive paneTitle = description } ) { Text(description) } }, state = rememberTooltipState(), ) { SplitButtonDefaults.TrailingButton( checked = checked, onCheckedChange = { checked = it }, modifier = Modifier.heightIn(size).semantics { stateDescription = if (checked) "Expanded" else "Collapsed" contentDescription = description }, shapes = SplitButtonDefaults.trailingButtonShapesFor(size), contentPadding = SplitButtonDefaults.trailingButtonContentPaddingFor(size), ) { val rotation: Float by animateFloatAsState( targetValue = if (checked) 180f else 0f, label = "Trailing Icon Rotation", ) Icon( Icons.Filled.KeyboardArrowDown, modifier = Modifier.size(SplitButtonDefaults.trailingButtonIconSizeFor(size)) .graphicsLayer { this.rotationZ = rotation }, contentDescription = "Localized description", ) } } }, )
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material.icons.outlined.Edit import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.PlainTooltip import androidx.compose.material3.SplitButton import androidx.compose.material3.SplitButtonDefaults import androidx.compose.material3.Text import androidx.compose.material3.TooltipAnchorPosition import androidx.compose.material3.TooltipBox import androidx.compose.material3.TooltipDefaults import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.semantics.LiveRegionMode import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.liveRegion import androidx.compose.ui.semantics.paneTitle import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription var checked by remember { mutableStateOf(false) } val size = SplitButtonDefaults.MediumContainerHeight SplitButton( leadingButton = { SplitButtonDefaults.LeadingButton( onClick = { /* Do Nothing */ }, modifier = Modifier.heightIn(size), shapes = SplitButtonDefaults.leadingButtonShapesFor(size), contentPadding = SplitButtonDefaults.leadingButtonContentPaddingFor(size), ) { Icon( Icons.Filled.Edit, modifier = Modifier.size(SplitButtonDefaults.leadingButtonIconSizeFor(size)), contentDescription = "Localized description", ) Spacer(Modifier.size(ButtonDefaults.iconSpacingFor(size))) Text("Label", style = ButtonDefaults.textStyleFor(size)) } }, trailingButton = { val description = "Toggle Button" // Icon-only trailing button should have a tooltip for a11y. TooltipBox( positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above), tooltip = { PlainTooltip( modifier = Modifier.semantics { // TODO(b/496338253): Remove this modifier once bug where tooltip // text is not announced by a11y screen readers is resolved. liveRegion = LiveRegionMode.Assertive paneTitle = description } ) { Text(description) } }, state = rememberTooltipState(), ) { SplitButtonDefaults.TrailingButton( checked = checked, onCheckedChange = { checked = it }, modifier = Modifier.heightIn(size).semantics { stateDescription = if (checked) "Expanded" else "Collapsed" contentDescription = description }, shapes = SplitButtonDefaults.trailingButtonShapesFor(size), contentPadding = SplitButtonDefaults.trailingButtonContentPaddingFor(size), ) { val rotation: Float by animateFloatAsState( targetValue = if (checked) 180f else 0f, label = "Trailing Icon Rotation", ) Icon( Icons.Filled.KeyboardArrowDown, modifier = Modifier.size(SplitButtonDefaults.trailingButtonIconSizeFor(size)) .graphicsLayer { this.rotationZ = rotation }, contentDescription = "Localized description", ) } } }, )
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material.icons.outlined.Edit import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.PlainTooltip import androidx.compose.material3.SplitButton import androidx.compose.material3.SplitButtonDefaults import androidx.compose.material3.Text import androidx.compose.material3.TooltipAnchorPosition import androidx.compose.material3.TooltipBox import androidx.compose.material3.TooltipDefaults import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.semantics.LiveRegionMode import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.liveRegion import androidx.compose.ui.semantics.paneTitle import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription var checked by remember { mutableStateOf(false) } val size = SplitButtonDefaults.LargeContainerHeight SplitButton( leadingButton = { SplitButtonDefaults.LeadingButton( onClick = { /* Do Nothing */ }, modifier = Modifier.heightIn(size), shapes = SplitButtonDefaults.leadingButtonShapesFor(size), contentPadding = SplitButtonDefaults.leadingButtonContentPaddingFor(size), ) { Icon( Icons.Filled.Edit, modifier = Modifier.size(SplitButtonDefaults.leadingButtonIconSizeFor(size)), contentDescription = "Localized description", ) Spacer(Modifier.size(ButtonDefaults.iconSpacingFor(size))) Text("Label", style = ButtonDefaults.textStyleFor(size)) } }, trailingButton = { val description = "Toggle Button" // Icon-only trailing button should have a tooltip for a11y. TooltipBox( positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above), tooltip = { PlainTooltip( modifier = Modifier.semantics { // TODO(b/496338253): Remove this modifier once bug where tooltip // text is not announced by a11y screen readers is resolved. liveRegion = LiveRegionMode.Assertive paneTitle = description } ) { Text(description) } }, state = rememberTooltipState(), ) { SplitButtonDefaults.TrailingButton( checked = checked, onCheckedChange = { checked = it }, modifier = Modifier.heightIn(size).semantics { stateDescription = if (checked) "Expanded" else "Collapsed" contentDescription = description }, shapes = SplitButtonDefaults.trailingButtonShapesFor(size), contentPadding = SplitButtonDefaults.trailingButtonContentPaddingFor(size), ) { val rotation: Float by animateFloatAsState( targetValue = if (checked) 180f else 0f, label = "Trailing Icon Rotation", ) Icon( Icons.Filled.KeyboardArrowDown, modifier = Modifier.size(SplitButtonDefaults.trailingButtonIconSizeFor(size)) .graphicsLayer { this.rotationZ = rotation }, contentDescription = "Localized description", ) } } }, )
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.KeyboardArrowDown import androidx.compose.material.icons.outlined.Edit import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.PlainTooltip import androidx.compose.material3.SplitButton import androidx.compose.material3.SplitButtonDefaults import androidx.compose.material3.Text import androidx.compose.material3.TooltipAnchorPosition import androidx.compose.material3.TooltipBox import androidx.compose.material3.TooltipDefaults import androidx.compose.material3.rememberTooltipState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.semantics.LiveRegionMode import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.liveRegion import androidx.compose.ui.semantics.paneTitle import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription var checked by remember { mutableStateOf(false) } val size = SplitButtonDefaults.ExtraLargeContainerHeight SplitButton( leadingButton = { SplitButtonDefaults.LeadingButton( onClick = { /* Do Nothing */ }, modifier = Modifier.heightIn(size), shapes = SplitButtonDefaults.leadingButtonShapesFor(size), contentPadding = SplitButtonDefaults.leadingButtonContentPaddingFor(size), ) { Icon( Icons.Filled.Edit, modifier = Modifier.size(SplitButtonDefaults.leadingButtonIconSizeFor(size)), contentDescription = "Localized description", ) Spacer(Modifier.size(ButtonDefaults.iconSpacingFor(size))) Text("Label", style = ButtonDefaults.textStyleFor(size)) } }, trailingButton = { val description = "Toggle Button" // Icon-only trailing button should have a tooltip for a11y. TooltipBox( positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above), tooltip = { PlainTooltip( modifier = Modifier.semantics { // TODO(b/496338253): Remove this modifier once bug where tooltip // text is not announced by a11y screen readers is resolved. liveRegion = LiveRegionMode.Assertive paneTitle = description } ) { Text(description) } }, state = rememberTooltipState(), ) { SplitButtonDefaults.TrailingButton( checked = checked, onCheckedChange = { checked = it }, // When the leading button text wraps to multiple lines (e.g., long text or // large // display settings), the trailing button might be shorter than the parent // container. // fillMaxHeight ensures it fills the full synchronized height. modifier = Modifier.fillMaxHeight().heightIn(size).semantics { stateDescription = if (checked) "Expanded" else "Collapsed" contentDescription = description }, shapes = SplitButtonDefaults.trailingButtonShapesFor(size), contentPadding = SplitButtonDefaults.trailingButtonContentPaddingFor(size), ) { val rotation: Float by animateFloatAsState( targetValue = if (checked) 180f else 0f, label = "Trailing Icon Rotation", ) Icon( Icons.Filled.KeyboardArrowDown, modifier = Modifier.size(SplitButtonDefaults.trailingButtonIconSizeFor(size)) .graphicsLayer { this.rotationZ = rotation }, contentDescription = "Localized description", ) } } }, )
Choose the best split button for an action based on the amount of emphasis it needs. The more important an action is, the higher emphasis its button should be.
Use SplitButtonDefaults.LeadingButton and SplitButtonDefaults.TrailingButton to construct a FilledSplitButton. Filled split button is the high-emphasis version of split button. It should be used for emphasizing important or final actions.
Use SplitButtonDefaults.TonalLeadingButton and SplitButtonDefaults.TonalTrailingButton to construct a tonal SplitButton. Tonal split button is the medium-emphasis version of split buttons. It's a middle ground between filled SplitButton and outlined SplitButton
Use SplitButtonDefaults.ElevatedLeadingButton and SplitButtonDefaults.ElevatedTrailingButton to construct a elevated SplitButton. Elevated split buttons are essentially tonal SplitButtons with a shadow. To prevent shadow creep, only use them when absolutely necessary, such as when the button requires visual separation from patterned container.
Use SplitButtonDefaults.OutlinedLeadingButton and SplitButtonDefaults.OutlinedTrailingButton to construct an outlined SplitButton. Outlined split buttons are medium-emphasis buttons. They contain actions that are important, but are not the primary action in an app. Outlined buttons pair well with filled SplitButtons to indicate an alternative, secondary action.
| Parameters | |
|---|---|
leadingButton: @Composable () -> Unit |
the leading button. You can specify your own composable or construct a |
trailingButton: @Composable () -> Unit |
the trailing button. You can specify your own composable or construct a |
modifier: Modifier = Modifier |
the |
spacing: Dp = SplitButtonDefaults.Spacing |
The spacing between the |