You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中ExposedDropDownMenu无法展开显示完整列表

问题:Jetpack Compose ExposedDropDownMenu仅显示第一个条目

使用Jetpack Compose的ExposedDropDownMenu时,菜单展开后只能显示列表中的第一个条目,尝试将OutlinedTextField的readOnly设为true或false均无法解决问题。编写的完整代码如下:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Combobox() {
val contextForToast = LocalContext.current.applicationContext
val listItems = arrayOf("Favorites", "Options", "Settings", "Share")

// state of the menu
var expanded by remember {
    mutableStateOf(false)
}

// remember the selected item
var selectedItem by remember {
    mutableStateOf(listItems[0])
}

// box
ExposedDropdownMenuBox(
    expanded = expanded,
    onExpandedChange = {
        expanded = !expanded
    }
) {
    OutlinedTextField(
        value = selectedItem,
        onValueChange = { selectedItem = it },
        modifier = Modifier.menuAnchor(),
        //readOnly = true,
        label = { Text(text = "Label") },
        trailingIcon = {
            ExposedDropdownMenuDefaults.TrailingIcon(
                expanded = expanded
            )
        },
        colors = ExposedDropdownMenuDefaults.textFieldColors()
    )

    // filter options based on text field value
    val filteringOptions =
        listItems.filter { it.contains(selectedItem, ignoreCase = true) }

    if (filteringOptions.isNotEmpty()) {
        // menu
        ExposedDropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false }
        ) {
            // this is a column scope
            // all the items are added vertically
            filteringOptions.forEach { selectionOption ->
                // menu item
                DropdownMenuItem(
                    text = {Text(text = selectionOption)},
                    onClick = {
                        selectedItem = selectionOption
                        Toast.makeText(contextForToast, selectedItem, Toast.LENGTH_SHORT).show()
                        expanded = false
                    },
                    contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
                )
            }
        }
    }
}

模拟器局部截图


解决方法

问题根源在于过滤逻辑错误:当前用selectedItem(已选中的条目)来过滤列表,默认选中第一个条目"Favorites"时,过滤结果只会包含包含该字符串的条目(也就是只有"Favorites"自己),所以菜单仅显示这一项。根据需求可以选择两种修改方式:

方式1:移除过滤,显示所有选项

如果不需要搜索过滤功能,直接去掉过滤逻辑,使用原列表即可:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Combobox() {
    val contextForToast = LocalContext.current.applicationContext
    val listItems = arrayOf("Favorites", "Options", "Settings", "Share")

    var expanded by remember { mutableStateOf(false) }
    var selectedItem by remember { mutableStateOf(listItems[0]) }

    ExposedDropdownMenuBox(
        expanded = expanded,
        onExpandedChange = { expanded = !expanded }
    ) {
        OutlinedTextField(
            value = selectedItem,
            onValueChange = { selectedItem = it },
            modifier = Modifier.menuAnchor(),
            readOnly = true, // 推荐设为true,避免手动输入干扰选中逻辑
            label = { Text(text = "Label") },
            trailingIcon = {
                ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
            },
            colors = ExposedDropdownMenuDefaults.textFieldColors()
        )

        // 直接使用原列表,移除错误的过滤逻辑
        if (listItems.isNotEmpty()) {
            ExposedDropdownMenu(
                expanded = expanded,
                onDismissRequest = { expanded = false }
            ) {
                listItems.forEach { selectionOption ->
                    DropdownMenuItem(
                        text = { Text(text = selectionOption) },
                        onClick = {
                            selectedItem = selectionOption
                            Toast.makeText(contextForToast, selectedItem, Toast.LENGTH_SHORT).show()
                            expanded = false
                        },
                        contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
                    )
                }
            }
        }
    }
}

方式2:实现实时输入过滤(如需搜索功能)

如果需要根据输入框内容过滤选项,需要将输入文本状态和选中条目状态分开,避免用已选中的条目作为过滤条件:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Combobox() {
    val contextForToast = LocalContext.current.applicationContext
    val listItems = arrayOf("Favorites", "Options", "Settings", "Share")

    var expanded by remember { mutableStateOf(false) }
    // 输入框的实时文本
    var inputText by remember { mutableStateOf(listItems[0]) }
    // 最终选中的条目
    var selectedItem by remember { mutableStateOf(listItems[0]) }

    ExposedDropdownMenuBox(
        expanded = expanded,
        onExpandedChange = { expanded = !expanded }
    ) {
        OutlinedTextField(
            value = inputText,
            onValueChange = { 
                inputText = it
                // 输入时自动展开菜单
                expanded = true
            },
            modifier = Modifier.menuAnchor(),
            readOnly = false, // 允许输入以实现过滤
            label = { Text(text = "Label") },
            trailingIcon = {
                ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
            },
            colors = ExposedDropdownMenuDefaults.textFieldColors()
        )

        // 用输入框的实时文本过滤列表
        val filteringOptions = listItems.filter { 
            it.contains(inputText, ignoreCase = true) 
        }

        if (filteringOptions.isNotEmpty()) {
            ExposedDropdownMenu(
                expanded = expanded,
                onDismissRequest = { expanded = false }
            ) {
                filteringOptions.forEach { selectionOption ->
                    DropdownMenuItem(
                        text = { Text(text = selectionOption) },
                        onClick = {
                            selectedItem = selectionOption
                            inputText = selectionOption // 同步输入框文本
                            Toast.makeText(contextForToast, selectedItem, Toast.LENGTH_SHORT).show()
                            expanded = false
                        },
                        contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
                    )
                }
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者jetberrocal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 02:11:00