如何在Jetpack Compose中控制下拉菜单的位置

23

我有一行文字在开头对齐和一张图片在末尾对齐。当我点击图片时,我显示一个DropdownMenu,但它出现在行的开头,而我想它出现在行的末尾。

我正在尝试在Modifier组件中使用Alignment.centerEnd,但它不起作用。

我该如何让弹出窗口出现在行的末尾?

@Composable
fun DropdownDemo(currentItem: CartListItems) {
    var expanded by remember { mutableStateOf(false) }
    Box(modifier = Modifier
        .fillMaxWidth()) {
        Text(modifier = Modifier.align(Alignment.TopStart),
            text = currentItem.type,
            color = colorResource(id = R.color.app_grey_dark),
            fontSize = 12.sp)
        Image(painter = painterResource(R.drawable.three_dots),
            contentDescription = "more options button",
            Modifier
                .padding(top = 5.dp, bottom = 5.dp, start = 5.dp)
                .align(Alignment.CenterEnd)
                .width(24.dp)
                .height(6.75.dp)
                .clickable(indication = null,
                    interactionSource = remember { MutableInteractionSource() },
                    onClick = {
                        expanded = true
                    }))
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false },
            modifier = Modifier
                .background(
                    Color.LightGray
                ).align(Alignment.CenterEnd),
        ) {
            DropdownMenuItem(onClick = { expanded = false }) {
                Text("Delete")
            }
            DropdownMenuItem(onClick = { expanded = false }) {
                Text("Save")
            }
        }
    }
}
3个回答

54
根据文档所述:

DropdownMenu 的行为类似于 Popup,并将使用父布局的位置来将自身定位到屏幕上。

您需要将 DropdownMenu 与调用视图一起放入一个 Box 中。在这种情况下,DropdownMenu 会出现在调用视图下方。
var expanded by remember { mutableStateOf(false) }
Column {
    Text("Some text")
    Box {
        Image(
            painter = painterResource(R.drawable.test),
            contentDescription = "more options button",
            modifier = Modifier
                .clickable {
                    expanded = true
                }
        )
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false },
        ) {
            DropdownMenuItem(onClick = { expanded = false }) {
                Text("Delete")
            }
            DropdownMenuItem(onClick = { expanded = false }) {
                Text("Save")
            }
        }
    }
}

3
这段代码片段将始终在左侧显示下拉菜单。有没有办法让它显示在中心? - kc_dev
1
@kc_dev 它实际上会自动检测方向,如果右侧没有可用的空间来显示,则会在左侧显示。我不确定材料指南是否认为居中显示是一个好主意,如果您找到这样的信息-您可以打开一个功能请求。到目前为止,您唯一可以调整的是offset-您需要像这里所示测量元素的宽度,并将该值的一半添加到offset参数中。 - Phil Dukhov
2
请注意,在 Android Studio 中的 实时预览 中,菜单始终位于屏幕的左上角。但是在模拟器或实际设备上,位置是正确的。 - nitro_nitrat

1
使用DropdownMenu()的偏移参数。请参考此链接
DropdownMenu(
    offset = DpOffset(x = (-66).dp, y = (-10).dp)
)

更改xy的值。它们接受正数和负数。


这样做会表现得太奇怪了。 - Fayaz
1
你能解释一下代码和数值吗? - Tippu Fisal Sheriff
请参考此指南:https://semicolonspace.com/dropdown-menu-jetpack-compose/ - SemicolonSpace
为什么是-66和-10呢? - undefined

0
当我点击图片时,会显示一个下拉菜单,但是它出现在行的开头,我希望它出现在行的末尾。
这很容易实现。在DropdownMenu的父级Box上使用contentAlignment = Alignment.TopStart
但也可以通过使用Modifier.pointerInteropFilter()拦截触摸事件,在触摸位置放置DropDownMenu
Column(Modifier.padding(12.dp)) {
  var offset = Offset.Zero
  var dropDownExpanded by remember { mutableStateOf(false) }

  Card(
      Modifier.fillMaxWidth()
          .shadow(1.dp, CardDefaults.shape)
          .pointerInteropFilter {
            offset = Offset(it.x, it.y)
            false
          }
          .combinedClickable(onClick = {}, onLongClick = { dropDownExpanded = true })) {
        Box(contentAlignment = Alignment.TopStart) {
          Text(
              "Long press me",
              Modifier.fillMaxWidth().padding(vertical = 50.dp),
              textAlign = TextAlign.Center)
          Box {
            DropdownMenu(
                expanded = dropDownExpanded,
                offset = DpOffset(pxToDp(offset.x), pxToDp(offset.y)),
                onDismissRequest = { dropDownExpanded = false }) {
                  DropdownMenuItem(
                      text = { Text("Dismiss me") }, onClick = { dropDownExpanded = false })
                }
          }
        }
      }
}

结果:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接