Android的输入法弹出问题,一直是困扰很多开发人员的问题,当输入法弹出时,布局会被压缩,某些控件被遮挡住,但是需求可能并不想让该控件遮挡住,在做输入法的时候,你一定要知道这个属性,android:windowSoftInputMode,他有三个属性,分别是adjustUnspecified,adjustResize,adjustPan。我建议最好不要用默认的,即adjustUnspecified。
在这设置的值(除"stateUnspecified"和"adjustUnspecified"以外)将覆盖在主题中设置的值
各值的含义:
【A】stateUnspecified:软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置
【B】stateUnchanged:当这个activity出现时,软键盘将一直保持在上一个activity里的状态,无论是隐藏还是显示
【C】stateHidden:用户选择activity时,软键盘总是被隐藏
【D】stateAlwaysHidden:当该Activity主窗口获取焦点时,软键盘也总是被隐藏的
【E】stateVisible:软键盘通常是可见的
【F】stateAlwaysVisible:用户选择activity时,软键盘总是显示的状态
【G】adjustUnspecified:默认设置,通常由系统自行决定是隐藏还是显示
【H】adjustResize:该Activity总是调整屏幕的大小以便留出软键盘的空间
【I】adjustPan:当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分
如下图所示:
当输入法弹出来的时候,会遮盖住登录按钮,但是我现在并不想输入法遮盖住登录按钮,同时希望背景也不会被压缩。
现在的需求是,当输入法弹出后,登录以上的布局(包括登录)向上移动到输入法之上,并且,背景不会被压缩。
如下所示:
如果想让弹出的输入法,保证界面背景图不被压缩,那么一定要使用adjustPan属性, **另外如果你的输入框上方是一个ListView或者RecyclerView,为保证列表显示完全,就需要设置qdjustResize属性**
可以在AndroidManifest文件中设置,也可以在代码中设置:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
看如下图所示的分析:
一个简单的模型,当输入法弹出的时候,可能登录按钮已经被遮盖住,那么我们只需要让登录按钮以上的布局通过scrollTo方式上移他被遮盖的距离就行了。
设置监听器:
private View.OnLayoutChangeListener onLayoutChangeListener = new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
Rect rect = new Rect();
// 获取root在窗体的可视区域
View root = getWindow().getDecorView();
root.getWindowVisibleDisplayFrame(rect);
// 当前视图最外层的高度减去现在所看到的视图的最底部的y坐标
int rootInvisibleHeight = root.getRootView().getHeight() - rect.bottom;
// 若rootInvisibleHeight高度大于100,则说明当前视图上移了,说明软键盘弹出了
if (rootInvisibleHeight > 100) {
//软键盘弹出来的时候
int[] location = new int[2];
// 获取scrollToView在窗体的坐标
mRlLogin.getLocationInWindow(location);
// 计算root滚动高度,使scrollToView在可见区域的底部
int scrollHeight = (location[1] + mRlLogin
.getHeight()) - rect.bottom;
root.scrollTo(0, scrollHeight);
} else {
// 软键盘没有弹出来的时候
root.scrollTo(0, 0);
}
}
};
在onResume时设置:
@Override
protected void onResume() {
super.onResume();
getWindow().getDecorView().addOnLayoutChangeListener(onLayoutChangeListener);
}