Android Compose DropdownMenu width 设置和父Box宽度一样
在 Compose 中,设置 DropdownMenu 的宽度与父 Box 的宽度相同需要一些技巧,因为 DropdownMenu 的宽度默认是由其内容决定的。 可以尝试以下方法:
- 使用 Modifier.width 和 IntrinsicSize
可以使用 Modifier.width(IntrinsicSize.Min) 来强制 DropdownMenu 的宽度与其内容的最小宽度相同,然后在父 Box 上使用 Modifier.onGloballyPositioned 获取其宽度,并将其设置为 DropdownMenu 的宽度。
var boxWidth by remember { mutableStateOf(0) }
Box(modifier = Modifier.onGloballyPositioned {
boxWidth = it.size.width
}) {
var expanded by remember { mutableStateOf(false) }
Button(onClick = { expanded = true }) {
Text("Open Dropdown")
}
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier =Modifier.width(with(LocalDensity.current){ boxWidth.toDp() })
) {
DropdownMenuItem(onClick = { /*TODO*/ }) {
Text("Item 1")
}
// ... other menu items
}
}
- 使用自定义布局
可以创建一个自定义布局,在其中测量父 Box 的宽度,并将其作为 DropdownMenu 的宽度约束。
@Composable
fun BoxWithDropdownMenu() {
var expanded by remember { mutableStateOf(false) }
Layout(
content = {
Button(onClick = { expanded = true }) {
Text("Open Dropdown")
}
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
DropdownMenuItem(onClick = { /*TODO*/ }) {
Text("Item 1")
}
// ... other menu items
}
}
) { measurables, constraints ->
val buttonMeasurable = measurables[0]
val dropdownMenuMeasurable = measurables[1]val buttonPlaceable = buttonMeasurable.measure(constraints)
val dropdownMenuPlaceable = dropdownMenuMeasurable.measure(
constraints.copy(minWidth = buttonPlaceable.width)
)
layout(dropdownMenuPlaceable.width, buttonPlaceable.height) {
buttonPlaceable.placeRelative(0, 0)
dropdownMenuPlaceable.placeRelative(0, buttonPlaceable.height)
}
}
}
这两种方法都可以实现 DropdownMenu 与父 Box 宽度相同的效果。选择哪种方法取决于具体需求和代码风格。