Use a segmented button to let users choose from a set of options, side-by-side. There are two types of segmented buttons:
- Single-select button: Lets users choose one option.
- Multi-select button: Lets users choose between two and five items. For more complex choices, or more than five items, use chips.
API surface
Use the SingleChoiceSegmentedButtonRow
and
MultiChoiceSegmentedButtonRow
layouts to create segmented buttons. These
layouts ensure that SegmentedButton
s are positioned and sized correctly,
and share the following key parameters:
space
: Adjusts the overlap between the buttons.content
: Contains the content of the segmented button row, which is typically a sequence ofSegmentedButton
s.
Create a single-select segmented button
This example shows how to create a single-select segmented button:
@Composable fun SingleChoiceSegmentedButton(modifier: Modifier = Modifier) { var selectedIndex by remember { mutableIntStateOf(0) } val options = listOf("Day", "Month", "Week") SingleChoiceSegmentedButtonRow { options.forEachIndexed { index, label -> SegmentedButton( shape = SegmentedButtonDefaults.itemShape( index = index, count = options.size ), onClick = { selectedIndex = index }, selected = index == selectedIndex, label = { Text(label) } ) } } }
Key points about the code
- Initializes a
selectedIndex
variable usingremember
andmutableIntStateOf
to track the currently selected button index. - Defines a list of
options
representing the button labels. SingleChoiceSegmentedButtonRow
ensures only one button can be selected.- Creates a
SegmentedButton
for each option, inside theforEachIndexed
loop:shape
defines the button's shape based on its index and the total count of options usingSegmentedButtonDefaults.itemShape
.onClick
updatesselectedIndex
with the clicked button's index.selected
sets the button's selection state based onselectedIndex
.label
displays the button label using theText
composable.
Result
Create a multi-select segmented button
This example shows how to create a multi-choice segmented button with icons that lets users select multiple options:
@Composable fun MultiChoiceSegmentedButton(modifier: Modifier = Modifier) { val selectedOptions = remember { mutableStateListOf(false, false, false) } val options = listOf("Walk", "Ride", "Drive") MultiChoiceSegmentedButtonRow { options.forEachIndexed { index, label -> SegmentedButton( shape = SegmentedButtonDefaults.itemShape( index = index, count = options.size ), checked = selectedOptions[index], onCheckedChange = { selectedOptions[index] = !selectedOptions[index] }, icon = { SegmentedButtonDefaults.Icon(selectedOptions[index]) }, label = { when (label) { "Walk" -> Icon( imageVector = Icons.AutoMirrored.Filled.DirectionsWalk, contentDescription = "Directions Walk" ) "Ride" -> Icon( imageVector = Icons.Default.DirectionsBus, contentDescription = "Directions Bus" ) "Drive" -> Icon( imageVector = Icons.Default.DirectionsCar, contentDescription = "Directions Car" ) } } ) } } }
Key points about the code
- The code initializes the
selectedOptions
variable usingremember
andmutableStateListOf
. This tracks the selected state of each button. - The code uses
MultiChoiceSegmentedButtonRow
to contain the buttons. - Inside the
forEachIndexed
loop, the code creates aSegmentedButton
for each option:shape
defines the button's shape based on its index and the total count of options.checked
sets the button's checked state based on the corresponding value inselectedOptions
.onCheckedChange
toggles the selected state of the corresponding item inselectedOptions
when the button is clicked.icon
displays an icon based onSegmentedButtonDefaults.Icon
and the button's checked state.label
displays an icon corresponding to the label, usingIcon
composables with appropriate image vectors and content descriptions.
Result
Additional resources
- Material 3: Segmented buttons