SplitButton
Common
Component in Material 3 Compose
A [SplitButton] let user 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.
Last updated:
Installation
dependencies {
implementation("androidx.compose.material3:material3:1.4.0-alpha01")
}
Overloads
@ExperimentalMaterial3ExpressiveApi
@Composable
fun SplitButton(
leadingButton: @Composable () -> Unit,
trailingButton: @Composable () -> Unit,
modifier: Modifier = Modifier,
spacing: Dp = SplitButtonDefaults.Spacing,
)
Parameters
name | description |
---|---|
leadingButton | the leading button. You can specify your own composable or construct a [SplitButtonDefaults.LeadingButton] |
trailingButton | the trailing button.You can specify your own composable or construct a [SplitButtonDefaults.TrailingButton] |
modifier | the [Modifier] to be applied to this split button. |
spacing | The spacing between the [leadingButton] and [trailingButton] |
Code Examples
SplitButtonSample
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@Preview
fun SplitButtonSample() {
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 = {
SplitButtonDefaults.TrailingButton(
onClick = { checked = !checked },
checked = checked,
modifier =
Modifier.semantics {
stateDescription = if (checked) "Checked" else "Unchecked"
contentDescription = "Toggle Button"
},
) {
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"
)
}
}
)
}
SplitButtonWithTextSample
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@Preview
fun SplitButtonWithTextSample() {
var checked by remember { mutableStateOf(false) }
SplitButton(
leadingButton = {
SplitButtonDefaults.LeadingButton(
onClick = { /* Do Nothing */ },
) {
Text("My Button")
}
},
trailingButton = {
SplitButtonDefaults.TrailingButton(
onClick = { checked = !checked },
checked = checked,
) {
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"
)
}
}
)
}
SplitButtonWithIconSample
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@Preview
fun SplitButtonWithIconSample() {
var checked by remember { mutableStateOf(false) }
SplitButton(
leadingButton = {
SplitButtonDefaults.LeadingButton(
onClick = { /* Do Nothing */ },
) {
Icon(
Icons.Filled.Edit,
contentDescription = "Localized description",
Modifier.size(SplitButtonDefaults.LeadingIconSize)
)
}
},
trailingButton = {
SplitButtonDefaults.TrailingButton(
onClick = { checked = !checked },
checked = checked,
) {
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"
)
}
}
)
}