【问题标题】:Jetpack Compose - DropdownMenu / Composable is placed outside (the) BoxJetpack Compose - DropdownMenu / Composable 放置在 (the) Box 之外
【发布时间】:2021-09-27 18:58:47
【问题描述】:

我正在尝试为我的应用程序制作一个自定义 TopBar,我希望在屏幕右上角显示一个 DropdownMenu。我有一个Box,其中包含一个Row(带有一些文本和图标)和一个最初不显示的DropdownMenu。当我单击一个图标时,会显示DropdownMenu,但在Box 之外,所以不是我想要的。代码:

@Composable
private fun TopBar {
    var expanded by remember { mutableStateOf(false) }
    Box(
        modifier = Modifier
            .border(1.dp, Color.Black)
    ) {
        Row(
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                text = "Ride history",
                maxLines = 1,
                fontSize = 25.sp
            )

            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.End
            ) {
                IconButton(
                    onClick = {}) {
                    Icon(imageVector = Icons.Filled.Search, contentDescription = null)
                }
                IconButton(
                    onClick = { expanded = !expanded }) {
                    Icon(imageVector = Icons.Filled.Sort, contentDescription = null)
                }
                IconButton(
                    onClick = { findNavController().navigate(RideFragmentDirections.actionRideFragmentToSettingsFragment())}) {
                    Icon(imageVector = Icons.Filled.Settings, contentDescription = null)
                }
            }
        }
        DropdownMenu(
            modifier = Modifier.align(Alignment.TopEnd),
            expanded = expanded,
            onDismissRequest = { expanded = false }
        ) {
            DropdownMenuItem(onClick = {}) {
                Text(text = "BlaBla")
            }
            DropdownMenuItem(onClick = {}) {
                Text(text = "BlaBla")
            }
        }
    }
}

我得到了什么:

(我在 Box 周围设置了一个边框以查看其边界)

按下排序按钮后,DropdownMenu 出现,但它位于Box 之外。我希望它被放置在右上角,覆盖所有内容。我错过了什么?

更新

@Composable
private fun TopBar() {
    var expanded by remember { mutableStateOf(false) }
    Box(
        modifier = Modifier
            .border(1.dp, Color.Black)
    ) {
        Row(
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                text = "Ride history",
                maxLines = 1,
                fontSize = 25.sp
            )

            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.End
            ) {
                IconButton(
                    onClick = {}
                ) {
                    Icon(imageVector = Icons.Filled.Search, contentDescription = null)
                }
                IconButton(
                    onClick = { expanded = !expanded }
                ) {
                    Icon(imageVector = Icons.Filled.Sort, contentDescription = null)
                }
                IconButton(
                    onClick = {}
                ) {
                    Icon(imageVector = Icons.Filled.Settings, contentDescription = null)
                }
            }
        }
        Box(
            modifier = Modifier.fillMaxHeight().align(Alignment.TopEnd),
            contentAlignment = Alignment.TopEnd
        ) {
            DropdownMenu(
                expanded = expanded,
                onDismissRequest = { expanded = false }
            ) {
                DropdownMenuItem(onClick = {}) {
                    Text(text = "BlaBla")
                }
                DropdownMenuItem(onClick = {}) {
                    Text(text = "BlaBla")
                }
            }
        }
    }
}

这会产生:

【问题讨论】:

  • 尝试将 DropdownMenu 放在另一个 Box 中,其中 contentAlignment = Alignment.TopStart
  • @PhilipDukhov 有点像!我用modifier = Modifier.align(Alignment.TopEnd), contentAlignment = Alignment.TopEnd ) 包裹了DropdownMenu,但这还不够。我的 dropdownMenu 显示在行的末尾,这很好,但不是在行的顶部而是在行的中心(图标被切成两半)。我认为这可能是由RowAlignment.CenterVertically 引起的,但我需要这个修饰符。
  • @LaC 谢谢。可惜还不够);
  • @daniyelp 你能用你得到的结果更新你的代码和图像吗?

标签: android android-jetpack-compose android-jetpack


【解决方案1】:

根据Material guidelines,下拉菜单应放在元素下方。

要在使用 DropdownMenu 的 Compose 中获得此布局,您需要将其放在带有调用按钮的 Box 中,如下所示:

Box {
    IconButton(
        onClick = { expanded = !expanded }
    ) {
        Icon(imageVector = Icons.Filled.Sort, contentDescription = null)
    }
    DropdownMenu(
        expanded = expanded,
        onDismissRequest = { expanded = false }
    ) {
        DropdownMenuItem(onClick = {}) {
            Text(text = "BlaBla")
        }
        DropdownMenuItem(onClick = {}) {
            Text(text = "BlaBla")
        }
    }
}

Sort 是调用按钮的输出:

【讨论】:

  • 看看我现在遇到了什么 xd:material.io/components/menus/android#dropdown-menusOverFlow Menus。所以这意味着我可以选择哪种菜单样式?
  • @daniyelp 是的,但目前 Compose 没有实现类似 OverflowMenu 的任何东西。你可以尝试自己实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-09-25
  • 2023-01-05
  • 1970-01-01
  • 1970-01-01
  • 2022-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多