之前写一个类似微信聊天界面的时候碰到了这个坑,本来认为EditText这种基础控件没啥好说的,没想到被软键盘坑了,网上找了很多方法都没有用,想了想还是整理一下。
碰到的问题很常见,EditText获取焦点后弹出软键盘遮挡住了聊天记录UI。
如下图所示:
当时想着这个问题很好解决嘛,不就是设置activity的windowSoftInputMode属性嘛?
android:windowSoftInputMode="adjustPan"
然并卵,把我TitleBar给顶出去了。
我们再看一眼官方文档
好像没什么毛病,在网上一搜是说这个自动伸缩的部分需要控件本身能伸缩,需要在想要伸缩的部分外面套上一个ScrollView。很显然套了没用,我的聊天记录是RecycleView,本身就可以伸缩,问题不在这。
接着我又试了fitsSystemWindows属性,还是没有用。
后来发现使用adjustResize的时候如果是全屏显示或者通过style设置沉浸式状态栏模式会失效。这不坑人吗?
于是我决定不使用adjustPan属性,而是使用adjustResize,自己去创建一个View,监听软键盘弹出事件,获取软键盘高度,然后用这个高度加载这个View去把原先的UI给顶起来。结果顶成了个麻花,这个View会在软键盘上方显示。
然而最终我还是找到了解决方案,那就是RecycleView去监听LayoutChange,然后发现底部改变后重新将RecycleView滚动到底部~
代码如下,用的是kotlin和databinding
mBinding.chatActivityRv.addOnLayoutChangeListener { v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom ->
MyLog.d(TAG,"onLayoutChanged")
if (bottom < oldBottom) {
mBinding.chatActivityRv.post {
if (mBinding.chatActivityRv.adapter!!.itemCount > 0) {
mBinding.chatActivityRv.smoothScrollToPosition(mBinding.chatActivityRv.adapter!!.itemCount-1)
}
}
}
}
最终效果:
总结一下主要的坑是android:windowSoftInputMode不支持沉浸式状态栏style,设置了fitsSystemWindows也没用,网上很多解决方案都是低版本SDK使用的,放在现在没有用~