我正在尝试在 Jetpack Compose 中实现可搜索的下拉菜单,但每当出现下拉菜单时,键盘就会失去焦点并消失。如何修改代码以防止键盘在下拉列表展开时消失?此外,如何确保下拉菜单始终保持锚定在按钮下方?这是我的代码的相关部分:
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SelectBox() {
var expanded by remember { mutableStateOf(false) }
var textInput by remember { mutableStateOf("") } // State to hold user input
var selectedDepartment by remember { mutableStateOf<String?>(null) }
val departments = DepartmentData.departments // Sample department data
val focusRequester = remember { FocusRequester() }
// Filtering departments based on user input
val filteredDepartments = departments.filter {
it.lowercase().contains(textInput.lowercase())
}
Box(modifier = Modifier
.fillMaxWidth()
.clickable { expanded = !expanded }) {
OutlinedTextField(
value = textInput,
onValueChange = {
textInput = it
if (it.isNotEmpty()) expanded = true
},
label = { Text("Department") },
modifier = Modifier
.fillMaxWidth()
.height(58.dp)
.focusRequester(focusRequester),
shape = RoundedCornerShape(8.dp),
singleLine = true,
trailingIcon = {
Icon(
imageVector = if (expanded) Icons.Default.KeyboardArrowUp else Icons.Default.KeyboardArrowDown,
contentDescription = "Dropdown toggle",
modifier = Modifier.clickable {
expanded = !expanded
focusRequester.requestFocus() // Maintain focus
}
)
},
colors = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = Color(0xFF153A99),
focusedLabelColor = Color(0xFF153A99)
)
)
DropdownMenu(
expanded = expanded,
onDismissRequest = {
expanded = false
focusRequester.requestFocus()
},
modifier = Modifier
.fillMaxWidth()
.heightIn(max = 100.dp)
) {
filteredDepartments.forEach { department ->
DropdownMenuItem(
text = { Text(department) },
onClick = {
selectedDepartment = department
textInput = department
expanded = false
focusRequester.requestFocus()
}
)
}
}
}
}
任何有关如何解决键盘关闭问题或如何正确锚定下拉菜单的建议将不胜感激。谢谢!
我删除了 OutlinedTextField 内的可点击修饰符,以防止重复的点击事件。 我在 DropdownMenu 和尾随图标的单击事件中调用 focusRequester.requestFocus() 来保持键盘焦点,无论下拉列表是展开还是折叠。
对于键盘消失的问题,可以将
focusable
中的DropdownMenu
属性设置为false。就文本字段下方的锚定下拉列表而言,当前代码将正常工作,除非您将此代码保留在Surface
中。
使用适当的锚点和键盘盒,下面的代码对我来说效果很好:
Box(modifier = Modifier.fillMaxWidth().clickable { expanded = !expanded }) {
OutlinedTextField(
value = textInput,
onValueChange = {
textInput = it
expanded = true
},
label = { Text("Department") },
modifier =
Modifier.fillMaxWidth().height(58.dp).focusRequester(focusRequester).onFocusChanged {
if (it.hasFocus) {
expanded = true
}
},
shape = RoundedCornerShape(8.dp),
singleLine = true,
trailingIcon = {
Icon(
imageVector =
if (expanded) Icons.Default.KeyboardArrowUp
else Icons.Default.KeyboardArrowDown,
contentDescription = "Dropdown toggle",
modifier =
Modifier.clickable {
expanded = !expanded
focusRequester.requestFocus() // Maintain focus
}
)
},
colors =
TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = Color(0xFF153A99),
focusedLabelColor = Color(0xFF153A99)
)
)
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier.fillMaxWidth(),
properties = PopupProperties(focusable = false),
) {
filteredDepartments.forEach { department ->
DropdownMenuItem(
text = { Text(department) },
onClick = {
selectedDepartment = department
textInput = department
expanded = false
}
)
}
}
}