Android Jetpack Compose Modal Bottom Sheet键盘弹出上移过度问题
Jetpack Compose Modal Bottom Sheet 键盘弹出后过度上移问题
问题现象
在Jetpack Compose中实现包含文本和输入框的简易Modal Bottom Sheet,正常显示无异常,但点击输入框弹出键盘后,底部弹窗被过度上移,底部边距相当于键盘高度的两倍。
相关代码
弹窗触发与显示代码
var showBottomSheet by remember { mutableStateOf(false) } if (showBottomSheet) { ModalBottomSheet( onDismissRequest = { showBottomSheet = false }, windowInsets = WindowInsets.ime, dragHandle = { BottomSheetDefaults.DragHandle() }, ) { CollectionFormPage() } }
弹窗内容代码
@Composable fun CollectionFormPage( collectionFormViewModel: CollectionFormViewModel = hiltViewModel(), ) { val state = collectionFormViewModel.state.collectAsState() Surface( modifier = Modifier .padding(start = 16.dp, end = 16.dp, bottom = 16.dp) ) { Column { Text( "Test", style = MaterialTheme.typography.titleMedium.copy( color = MaterialTheme.colorScheme.onSurface ) ) TextField( modifier = Modifier.fillMaxWidth(), value = state.value.label, onValueChange = { //TODO }) } } }
状态截图
- 正常显示状态:

- 异常状态:

解决方案
问题根源是**WindowInsets.ime的手动设置,与内容层的bottom = 16.dp padding叠加,加上ModalBottomSheet本身的自动IME适配逻辑,导致重复计算了键盘高度的偏移量**。
可以通过以下两种方式修复:
方式一:移除ModalBottomSheet的windowInsets参数
ModalBottomSheet默认已经内置了IME(输入法)的inset适配逻辑,无需手动指定WindowInsets.ime,移除该参数即可解决重复偏移问题:
ModalBottomSheet( onDismissRequest = { showBottomSheet = false }, dragHandle = { BottomSheetDefaults.DragHandle() }, ) { CollectionFormPage() }
方式二:动态调整内容层的底部padding
如果需要保留自定义windowInsets设置,可以在内容层的padding中减去IME的底部inset值,避免重复偏移:
@Composable fun CollectionFormPage( collectionFormViewModel: CollectionFormViewModel = hiltViewModel(), ) { val state = collectionFormViewModel.state.collectAsState() val imeBottomInset = WindowInsets.ime.getBottom(LocalDensity.current).toDp() Surface( modifier = Modifier .padding( start = 16.dp, end = 16.dp, bottom = max(16.dp - imeBottomInset, 0.dp) ) ) { // 原有内容保持不变 } }
推荐使用方式一,因为ModalBottomSheet的默认适配逻辑已经能满足键盘弹出场景,手动指定WindowInsets.ime反而会打破原有适配逻辑,引发异常偏移。
内容的提问来源于stack exchange,提问作者Rares Cruceat
相关产品推荐
相关产品推荐

