Android键盘切换闪动原理及解决方案
主要内容
键盘切换闪动原理
键盘切换闪动解决方案
- 设置键盘
softInputMode
使用adjustPan
,增加一个与键盘同高的支撑视图(不推荐) - 设置键盘
softInputMode
使用adjustResize
,在onMeasure时处理键盘事件
- 设置键盘
键盘切换闪动原理
上图中有几个状态(这里键盘softInputMode
为adjustResize
,如果对键盘弹出方式还不理解的可以自行Google):
状态1: 正常状态,键盘没有弹出
状态2: 键盘弹出状态
状态3: 执行从键盘切换到表情框操作过程中的一次Layout结果(这也就是跳动的关键所在!!!)
状态4: 切换之后显示表情框
下面简单介绍一下上面这些状态的切换:
状态1到状态2:
键盘弹出,Activity的根视图被挤压(也就是图片中(1)的高度发生变化)
状态2到状态3
在键盘显示的情况下切换表情框的操作(先隐藏键盘,然后设置表情框为visible)。
在调用表情框setVisiblity的时候会使界面重新layout,但这是键盘还没来得及隐藏,表情框又可见了,并且Activity的根视图还是被挤压的状态),然后表情框就会在Activity根视图底部出现(也就是键盘上面),这就是要处理的跳动的那一帧。
状态3到状态4
由于键盘隐藏重新layout,Activity根视图恢复到原始大小,表情框回到正确的位置,这就造成了跳下来的视觉效果。
键盘切换闪动解决方案
设置键盘softInputMode
使用adjustPan
,增加一个与键盘同高的支撑视图(不推荐)
从图中也可以看出Activity的根视图的大小一直都是不变的,原因是键盘的弹出方式为adjustPan
而且输入框又一直处于可见状态(被支撑板顶起)。
状态1:正常状态,键盘没有弹出
状态2:键盘弹出之前设置支撑板可见
状态3:键盘以adjustPan方式弹出,覆盖在支撑板之上
状态4: 切换键盘到表情框(支撑板不消失),然后马上显示表情框,这样也不会造成跳动,如果要隐藏键盘直接设置支撑板为不可见即可
状态5: 表情框显示在支撑板之上
具体的实现方式网上比较多,这里因为不推荐所以不做解释了,讲个原理就好了。
不推荐原因如下:
- 首先要获取到键盘的高度(必须使用
softInputMode
为adjustResize
然后通过监听Activity的根视图的onGlobalLayoutChange
事件,这里就意味着第一次键盘切换是没办法实现无缝切换的) softInputMode
切换逻辑比较复杂,支撑板的显示隐藏有时会因为一些比较特殊的操作导致不符合预期(可能出现又显示键盘又显示支撑板情况)。- 输入法高度改变时无法动态设置表情框跟支撑板的高度(因为
softInputMode
为adjustPan
不会造成onGlobalLayoutChange
事件) - 项目第一次使用的就是这种实现,经过几个月测试确实不稳定
设置键盘softInputMode
使用adjustResize
,在onMeasure时处理键盘事件
这里分析的基础都是基于开源项目JKeyboardPanelSwitch
原理图还是开始的那张
键盘的高度由于是adjustResize
所以可以通过OnGlobalLayoutChange
事件获取到,切换表情框的时候理想的效果直接从状态2直接到状态4,那样就不会出现状态3的那一帧,也就自然不会有跳动一下的视觉效果,解决跳动的思路也是从如何处理状态3这里着手。
我们其实要做的也很简单,就是处理掉状态2到状态4过程中那次不必要的layout就不会出现状态3,然后就可以完美地解决跳动的视觉效果,上面项目所用的方法就是重写表情框的setVisibility方法,然后把状态2到状态3的那次setVisibility过滤掉,然后就不会进行显示状态3的那次layout,就不会出现跳动的情况,具体可以参看其中代码实现。
这篇文章主要想记录一下自己在这方面遇到的问题跟一些感想,后一种实现思路由于有具体的代码可参看就不想再浪费时间去详细介绍了,如果存在什么问题还希望指出。