首页 > 解决方案 > Jetpack compose:可以设置 DropdownMenu 高度以显示下一项

问题描述

我正在使用DropdownMenuJetpack Compose,但我遇到了一个问题,即很多用户不明白菜单包含更多信息,因此他们可以滚动列表。我得到了很多支持,他们从列表中遗漏了一些东西。特别是在某些语言中,它很好地将高度与一个项目对齐,所以你看不到有更多的项目。

有没有办法自动设置下拉菜单的高度(无论语言),以便在底部显示一半的项目,以便用户了解他们可以滚动列表?

我使用这些修饰符创建菜单:

DropdownMenu(
    expanded = expanded,
    onDismissRequest = { expanded = false },
    modifier = Modifier.requiredSizeIn(maxHeight = 330.dp)
) {
        items.forEachIndexed { index, item ->
                DropdownMenuItem(onClick = {
                    onSelected(index, item.data)
                    selectedIndex = index
                    expanded = false
                }) {
...
}

标签: kotlinandroid-jetpack-compose

解决方案


我同意这是一个不错的功能,我建议您在 Compose 问题跟踪器上创建一个功能请求。

这是目前的解决方法,您可以使用以下方式获取项目高度Modifier.onSizeChanged并更新您的maxHeight约束:

@Composable
fun TestScreen(
) {
    var expanded by remember { mutableStateOf(true) }
    val items = List(10) { it.toString() }
    val itemHeights = remember { mutableStateMapOf<Int, Int>() }
    val baseHeight = 330.dp
    val density = LocalDensity.current
    val maxHeight = remember(itemHeights.toMap()) {
        if (itemHeights.keys.toSet() != items.indices.toSet()) {
            // if we don't have all heights calculated yet, return default value
            return@remember baseHeight
        }
        val baseHeightInt = with(density) { baseHeight.toPx().toInt() }

        // top+bottom system padding
        var sum = with(density) { DropdownMenuVerticalPadding.toPx().toInt() } * 2
        for ((i, itemSize) in itemHeights.toSortedMap()) {
            sum += itemSize
            if (sum >= baseHeightInt) {
                return@remember with(density) { (sum - itemSize / 2).toDp() }
            }
        }
        // all items fit into base height
        baseHeight
    }

    DropdownMenu(
        expanded = expanded,
        onDismissRequest = { expanded = false },
        modifier = Modifier.requiredSizeIn(maxHeight = maxHeight)
    ) {
        items.forEachIndexed { index, item ->
            DropdownMenuItem(
                onClick = {
                    onSelected(index, item.data)
                    selectedIndex = index
                    expanded = false
                },
                modifier = Modifier.onSizeChanged {
                    itemHeights[index] = it.height
                }
            ) {
                Text("Hello $index", modifier = Modifier.padding(30.dp))
            }
        }
    }
}

private val DropdownMenuVerticalPadding = 8.dp

psDropdownMenuVerticalPadding是取自源代码的材料常数。


推荐阅读