Material Design dropdown menu Menus display a list of choices on a temporary surface.
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Preview
@Sampled
@Composable
fun ExposedDropdownMenuSample() {
val options: List<String> = SampleData.take(5)
var expanded by remember { mutableStateOf(false) }
val textFieldState = rememberTextFieldState(options[0])
var checkedIndex by rememberSaveable { mutableIntStateOf(0) }
ExposedDropdownMenuBox(expanded = expanded, onExpandedChange = { expanded = it }) {
TextField(
// The `menuAnchor` modifier must be passed to the text field to handle
// expanding/collapsing the menu on click. A read-only text field has
// the anchor type `PrimaryNotEditable`.
modifier = Modifier.menuAnchor(ExposedDropdownMenuAnchorType.PrimaryNotEditable),
state = textFieldState,
readOnly = true,
lineLimits = TextFieldLineLimits.SingleLine,
label = { Text("Label") },
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
colors = ExposedDropdownMenuDefaults.textFieldColors(),
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
containerColor = MenuDefaults.groupStandardContainerColor,
shape = MenuDefaults.standaloneGroupShape,
) {
val optionCount = options.size
options.forEachIndexed { index, option ->
SelectableDropdownMenuItem(
shapes = MenuDefaults.itemShape(index, optionCount),
text = { Text(option, style = MaterialTheme.typography.bodyLarge) },
selected = index == checkedIndex,
onClick = {
textFieldState.setTextAndPlaceCursorAtEnd(option)
checkedIndex = index
expanded = false
},
selectedLeadingIcon = {
Icon(
Icons.Filled.Check,
modifier = Modifier.size(MenuDefaults.LeadingIconSize),
contentDescription = null,
)
},
contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
)
}
}
}
}