The M2(从版本开始1.1.0-alpha06 https://developer.android.com/jetpack/androidx/releases/compose-material#1.1.0-alpha06) and M3有实施ExposedDropdownMenu
基于ExposedDropdownMenuBox
with TextField
and DropdownMenu
inside.
就像是:
val options = listOf("Option 1", "Option 2", "Option 3", "Option 4", "Option 5")
var expanded by remember { mutableStateOf(false) }
var selectedOptionText by remember { mutableStateOf(options[0]) }
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = {
expanded = !expanded
}
) {
TextField(
readOnly = true,
value = selectedOptionText,
onValueChange = { },
label = { Text("Label") },
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(
expanded = expanded
)
},
colors = ExposedDropdownMenuDefaults.textFieldColors()
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = {
expanded = false
}
) {
options.forEach { selectionOption ->
DropdownMenuItem(
onClick = {
selectedOptionText = selectionOption
expanded = false
}
){
Text(text = selectionOption)
}
}
}
}
![enter image description here](https://i.stack.imgur.com/JxPV5.png)
如果您正在使用M3 (androidx.compose.material3
)你还必须通过menuAnchor
修饰符为TextField
:
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = !expanded },
) {
TextField(
//...
modifier = Modifier.menuAnchor()
)
ExposedDropdownMenu(){ /*.. */ }
}
同样在M3中DropdownMenuItem
你必须移动内容text
范围:
DropdownMenuItem(
text = { Text(text = selectionOption) },
onClick = {
selectedOptionText = selectionOption
expanded = false
}
)
搭配M2版本1.0.x
没有内置组件。
您可以使用OutlinedTextField
+ DropdownMenu
。将它们包裹在一个很重要的地方Box
。这样,文本字段将用作“锚点”。
这只是一个基本(非常基本)的实现:
var expanded by remember { mutableStateOf(false) }
val suggestions = listOf("Item1","Item2","Item3")
var selectedText by remember { mutableStateOf("") }
var textfieldSize by remember { mutableStateOf(Size.Zero)}
val icon = if (expanded)
Icons.Filled.ArrowDropUp //it requires androidx.compose.material:material-icons-extended
else
Icons.Filled.ArrowDropDown
Box() {
OutlinedTextField(
value = selectedText,
onValueChange = { selectedText = it },
modifier = Modifier
.fillMaxWidth()
.onGloballyPositioned { coordinates ->
//This value is used to assign to the DropDown the same width
textfieldSize = coordinates.size.toSize()
},
label = {Text("Label")},
trailingIcon = {
Icon(icon,"contentDescription",
Modifier.clickable { expanded = !expanded })
}
)
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier
.width(with(LocalDensity.current){textfieldSize.width.toDp()})
) {
suggestions.forEach { label ->
DropdownMenuItem(onClick = {
selectedText = label
}) {
Text(text = label)
}
}
}
}