场景:全屏模式下activity的adjustResize 失效,弹键盘时候底部的输入框无法自动调整到键盘区域的上方
1. 方案一:
使用 AndroidBug5497Workaround (https://stackoverflow.com/questions/7417123/android-how-to-adjust-layout-in-full-screen-mode-when-softkeyboard-is-visible)
原理:通过 getViewTreeObserver().addOnGlobalLayoutListener监听当前屏幕显示区域的大小,然后动态调整Activity rootView的height,实现“adjust resize”的效果
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
int usableHeightNow = r.bottom - r.top;
if (usableHeightNow != usableHeightPrevious) {
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
if (heightDifference > (usableHeightSansKeyboard/4)) {
// keyboard probably just became visible
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
} else {
// keyboard probably just became hidden
frameLayoutParams.height = usableHeightSansKeyboard;
}
mChildOfContent.requestLayout();
usableHeightPrevious = usableHeightNow;
但是这个不能完全解决我们问题,会遇到下面的问题:
在输入框在屏幕区域上方是没问题,在输入框在底部时候,会有一个特别不好的现象,键盘弹出后会迅速把整个Activity完全顶上去,然后调整回来。
问题的原因是是OnGlobalLayoutListener不是实时和键盘弹时屏幕显示区域同步的。所以就会在键盘弹起的瞬间先把整个activity顶上去,然后顶上去后,屏幕内容又会掉下来
补丁方案:
输入框在底部时候不要直接弹出键盘,先让顶部的一个1px的输入框获得这个这个焦点,待键盘完全弹出来后再把焦点传递给底部的这个输入框,这样就不会有顶整个界面起来的现象
补充问题
为什么在顶部的时候不会出现顶上去又下来的情况?
因为 输入框在最上面,键盘输入法只要弹出时不盖住输入框,就不会顶起这个Activity的内容,而内容区域调整也是延迟于键盘弹起速度的,但是由于键盘盖住了所以视觉感觉不出来
虚拟按键
注意android的虚拟按键有两种:
一种是N5 N6一类的固定在底部的虚拟按键
一种是华为 小米mix 一类的的 可以通过手势动态控制底部虚拟按键显示还隐藏
这种就需要动态计算高度
为了解决A问题,需要在顶部放置一个fake EditText ,点击目标EditText时候先让顶部的fakeEditText获得焦点,待键盘完全弹出来后再把焦点转移给目标EditText
具体方案:目标EditText监控ontouch事件,在TouchUp时候消耗掉这个事件,这样就不会触发键盘直接弹出来了,这时候,顶部的 fake EditText先获取焦点,延迟一段时间 待键盘完全弹出后再让目标EditText获取焦点
2.方案二
JkeyboardSwitch (https://github.com/Jacksgong/JKeyboardPanelSwitch)
原理是在输入框下面加了一个和键盘高度相同的panel,在键盘弹出来的瞬间panel显示出来(invisualble状态),这样键盘的弹出和隐藏与panel的的invisualble和gone的状态同步起来,看起来的效果就是键盘出来时候把输入框顶上去,键盘收起来时候把输入框收回去
这个方案的一个问题是“怎么在第一次弹出时候初始化panel高度和键盘高度一致?”
补丁方案:
第一次弹出瞬间把输入框的区域设置为Invisualbel ,初始panel的高度尽量大,待键盘完全弹出后把输入框区域显示出来,然后调整panel的高度,这样就能在用户无察觉的情况初始化这个panel高度。