Android Studio中Jetpack Compose实现点击Box任意位置显示DropdownMenu
我希望点击屏幕任意位置时显示DropdownMenu,但无法正常实现。尝试用offset设置下拉菜单的位置,却只有X轴的位置设置生效,Y轴偏移异常。相关代码如下:
var expanded by remember { mutableStateOf(false) } var touchPoint: Offset by remember { mutableStateOf(Offset.Zero) } val density = LocalDensity.current Box( Modifier .fillMaxSize() .background(Color.Cyan) .pointerInput(Unit) { detectTapGestures { Log.d(TAG, "onCreate: ${it}") touchPoint = it expanded = true } } ) { val (xDp, yDp) = with(density) { (touchPoint.x.toDp()) to (touchPoint.y.toDp()) } DropdownMenu( modifier = Modifier.align(Alignment.Center), expanded = expanded, offset = DpOffset(xDp, yDp), onDismissRequest = { expanded = false }, ) { DropdownMenuItem(onClick = { expanded = false }) { Text("Copy") } DropdownMenuItem(onClick = { expanded = false }) { Text("Get Balance") } } }

问题分析与解决方案
问题根源
Modifier.align(Alignment.Center)强制DropdownMenu在父布局中居中对齐,直接覆盖了你通过offset设置的Y轴偏移,导致Y轴设置无效。- DropdownMenu的
offset是相对于其布局锚点的偏移量,而非屏幕绝对坐标,原代码的坐标转换逻辑没问题,但被对齐属性干扰。
修正代码
移除Modifier.align(Alignment.Center),让DropdownMenu以父布局左上角为锚点,配合触摸点坐标设置偏移:
var expanded by remember { mutableStateOf(false) } var touchPoint: Offset by remember { mutableStateOf(Offset.Zero) } val density = LocalDensity.current Box( Modifier .fillMaxSize() .background(Color.Cyan) .pointerInput(Unit) { detectTapGestures { Log.d(TAG, "onCreate: ${it}") touchPoint = it expanded = true } } ) { val (xDp, yDp) = with(density) { touchPoint.x.toDp() to touchPoint.y.toDp() } DropdownMenu( expanded = expanded, offset = DpOffset(xDp, yDp), onDismissRequest = { expanded = false } ) { DropdownMenuItem(onClick = { expanded = false }) { Text("Copy") } DropdownMenuItem(onClick = { expanded = false }) { Text("Get Balance") } } }
额外优化
如果希望菜单显示在触摸点下方(避免重叠),可以对Y轴偏移做微调:
offset = DpOffset(xDp, yDp + 20.dp)
内容的提问来源于stack exchange,提问作者Mehranjp73
相关产品推荐
相关产品推荐

