Jetpack Compose Modifier.imePadding在小米设备上适配异常排查
小米设备Jetpack Compose输入法适配异常问题说明
问题表现
小米11、小米11T Pro等搭载MIUI的设备上,软键盘弹出时存在两类偶现异常:
- 界面仅滚动到输入框一半位置
- 输入框被软键盘完全遮挡
仅少数场景交互正常,其余品牌同版本安卓机型无该问题。
预期交互逻辑:点击输入框后,界面随软键盘弹出动画自动上移,最终将输入框贴合在软键盘顶部位置。
异常效果可参考原问题附带的适配异常截图。
现有配置
当前已做的适配逻辑如下:
AndroidManifest.xml对应Activity配置android:windowSoftInputMode="adjustResize"- 代码中已调用
WindowCompat.setDecorFitsSystemWindows(window, false)开启沉浸式配置 - 页面核心布局代码:
Column( modifier = Modifier .fillMaxSize() .background(SinsayAppTheme.colors.smoke) .imePadding() )
项目使用的Jetpack Compose版本为1.2.0-alpha07。
问题成因
该问题由两方面因素共同导致:
- MIUI系统篡改了AOSP原生的WindowInsets分发逻辑:部分MIUI版本在
setDecorFitsSystemWindows(window, false)的沉浸式场景下,不会在软键盘弹出动画过程中实时回调IME insets数值,仅在动画结束后一次性返回最终高度,甚至有概率返回比实际软键盘高度小1/2的错误值,直接导致Compose的imePadding()计算出的边距不准确。 - 当前项目使用的
1.2.0-alpha07为Compose早期alpha测试版,该版本的IME insets适配逻辑没有加入国产定制ROM的异常值兜底,无法识别小米设备返回的错误高度值,也没有做动画过程的差值补全。
修复方案
方案1:升级Compose版本(推荐,成本最低)
直接将Compose依赖升级到1.3.0及以上正式版即可。从1.3版本开始,Compose官方已经针对小米、华为等国产定制ROM的IME insets异常上报问题做了兼容,会自动校验返回的高度值合理性,同时补全了软键盘动画过程中的边距渐变逻辑,绝大多数小米机型升级后无需额外修改代码即可恢复正常交互。
方案2:自定义IME边距适配(无法升级版本时使用)
受项目依赖限制不能升级Compose版本时,可以手动实现IME高度监听逻辑,绕开系统和Compose默认的insets分发:
- 给页面根View设置固定id,在Activity中通过
ViewTreeObserver.OnGlobalLayoutListener监听布局变化,通过可见区域高度差计算真实的软键盘高度,避免采信系统返回的错误insets值。 - 自定义
safeImePadding()修饰符替换默认的imePadding(),对小米机型做特殊校验:当检测到系统返回的IME高度小于屏幕高度1/3、且当前输入框处于聚焦状态时,手动通过WindowInsetsAnimationCompat监听软键盘动画过程,逐帧更新布局边距。 - 可以针对MIUI设备单独加兜底配置:检测到系统为MIUI时,给对应Window添加私有flag
android:miui:windowSoftInputMode="adjustPan",避免出现输入框完全被遮挡的极端情况。
方案3:临时兜底方案
需要快速上线修复时,可以暂时将问题页面的windowSoftInputMode改为adjustPan,该模式下系统会自动平移整个界面保证输入框可见,缺点是没有跟随软键盘动画平滑滚动的效果,但可以100%避免输入框被遮挡的问题。
内容的提问来源于stack exchange,提问作者Paweł Krzyściak
相关产品推荐
相关产品推荐

