如何在 Jetpack Compose 中使用可搜索下拉菜单保持键盘焦点?

问题描述 投票:0回答:1

我正在尝试在 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() 来保持键盘焦点,无论下拉列表是展开还是折叠。

android kotlin android-jetpack-compose android-textinputlayout
1个回答
0
投票

对于键盘消失的问题,可以将

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
                }
            )
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.