如何让Android的Composable选择性忽略Manifest中的adjustResize设置?
实现部分Composable忽略adjustResize的方案
你可以通过两种方式实现需求,核心思路是让目标Composable不受adjustResize导致的布局尺寸变化影响:
方案一:基于真实屏幕高度固定布局位置
adjustResize会让布局的可用高度减去键盘高度,所以直接获取屏幕的真实物理高度,让目标Composable基于这个高度定位,就能跳过系统的布局调整:
- 先写一个Composable函数获取真实屏幕高度(转成dp):
@Composable fun getRealScreenHeightDp(): Int { val context = LocalContext.current val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager val displayMetrics = DisplayMetrics() windowManager.defaultDisplay.getRealMetrics(displayMetrics) return (displayMetrics.heightPixels / displayMetrics.density).toInt() }
- 在布局中给目标Composable自定义布局逻辑,用真实高度定位:
Box(modifier = Modifier.fillMaxSize()) { // 固定位置的内容,忽略键盘弹出的布局调整 Text( text = "不随键盘移动的文本", modifier = Modifier .layout { measurable, constraints -> val placeable = measurable.measure(constraints) // 基于真实屏幕高度计算固定位置,这里示例是距离顶部150dp val fixedTopY = 150.dp.roundToPx() layout(constraints.maxWidth, constraints.maxHeight) { placeable.placeRelative( x = (constraints.maxWidth - placeable.width) / 2, y = fixedTopY ) } } ) // 跟随键盘移动的底部内容 Button( onClick = {}, modifier = Modifier.align(Alignment.BottomCenter) ) { Text("键盘上方的按钮") } }
方案二:用键盘Insets抵消布局位移(更简洁)
利用LocalWindowInsets获取键盘的高度,给固定内容添加对应的底部padding,抵消adjustResize带来的布局上移:
- 封装一个容器Composable:
@Composable fun IgnoreAdjustResizeContainer(content: @Composable () -> Unit) { val imeInsets = LocalWindowInsets.current.ime val keyboardHeight = imeInsets.bottom.toDp() Box( modifier = Modifier .fillMaxSize() // 键盘弹出时,添加等于键盘高度的底部padding,抵消布局上移 .padding(bottom = if (imeInsets.isVisible) keyboardHeight else 0.dp) ) { content() } }
- 直接包裹需要固定的内容即可:
Box(modifier = Modifier.fillMaxSize()) { IgnoreAdjustResizeContainer { Text( text = "不随键盘移动的文本", modifier = Modifier.align(Alignment.TopCenter) ) } // 正常跟随键盘移动的底部按钮 Button( onClick = {}, modifier = Modifier.align(Alignment.BottomCenter) ) { Text("键盘上方的按钮") } }
两种方案都不需要修改WindowCompat.setDecorFitsSystemWindows的设置,完全基于Compose自身的布局逻辑实现需求。
内容的提问来源于stack exchange,提问作者Edna Krabappel
相关产品推荐
相关产品推荐

