我正在继续开发来自 AutoComplete 可组合项的 AutoComplete 可组合项,在弹出窗口可见时无法键入:
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AutoCompleteExample() {
Scaffold(topBar = { TopAppBar(title = { Text("AutoCompleteExample") }) }) { innerPadding ->
Column(modifier = Modifier.padding(innerPadding)) {
val names = listOf("Tony Stark", "Steve Rogers", "Bruce Banner", "Natasha Romanoff")
var name by remember { mutableStateOf("") }
val aliases = listOf("Iron Man", "Captain America", "Hulk", "Black Widow")
var alias by remember { mutableStateOf("") }
AutoComplete(
label = { Text("Name") },
options = names,
value = name,
onValueChange = { name = it },
)
AutoComplete(
value = alias,
options = aliases,
onValueChange = { name = it },
label = { Text("Alias") }
)
}
}
}
@Composable
fun AutoComplete(
label: @Composable () -> Unit,
options: List<String>,
value: String,
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
isError: Boolean = false,
) {
var expanded by remember { mutableStateOf(false) }
var filteredOpts by remember { mutableStateOf(options) }
Column {
TextField(
label = label,
value = value,
onValueChange = {
onValueChange(it)
filteredOpts = options.filter { option ->
option
.lowercase()
.contains(it.lowercase())
}
expanded = true
},
isError = isError,
keyboardOptions = keyboardOptions,
modifier = modifier
)
if (expanded && filteredOpts.isNotEmpty()) {
Column(
modifier = Modifier
.fillMaxWidth(),
) {
filteredOpts.forEach { option ->
DropdownMenuItem(
text = { Text(text = option) },
onClick = {
onValueChange(option)
filteredOpts = emptyList()
expanded = false
}
)
}
}
}
}
}
到目前为止一切顺利。但是,当用户开始输入时。这些建议将第二个自动完成功能进一步向下推,而不是在其之上渲染。我该如何解决这个问题?
也许您应该尝试使用
Popup
来过滤结果。
我稍微改变了你的代码,它并不完美,但看看这个:
@Composable
fun AutoComplete(
label: @Composable () -> Unit,
options: List<String>,
value: String,
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
isError: Boolean = false,
) {
var expanded by remember { mutableStateOf(false) }
var filteredOpts by remember { mutableStateOf(options) }
Column {
TextField(
label = label,
value = value,
onValueChange = {
onValueChange(it)
filteredOpts = options.filter { option ->
option
.lowercase()
.contains(it.lowercase())
}
expanded = true
},
isError = isError,
keyboardOptions = keyboardOptions,
modifier = modifier
)
if (expanded && filteredOpts.isNotEmpty()) {
Popup(
alignment = Alignment.TopStart,
offset = IntOffset(x = 0, y = 200),
properties = PopupProperties(
excludeFromSystemGesture = true,
),
// to dismiss on click outside
onDismissRequest = {
filteredOpts = emptyList()
expanded = false
}
) {
Column(
modifier = Modifier
.clip(RoundedCornerShape(12.dp))
) {
filteredOpts.forEach { option ->
Box(
Modifier
.wrapContentHeight()
.padding(vertical = 15.dp)
.background(Color.White)
.clickable {
onValueChange(option)
filteredOpts = emptyList()
expanded = false
},
contentAlignment = Alignment.Center
) {
Text(text = option)
}
}
}
}
}
}
}