windowSoftInputMode,解决软键盘遮挡住输入框的问题
今天在项目中遇到了一个软键盘遮挡住输入框的特殊案例,经过和搭档的研究,终于完美解决了。写下这篇文章,记录一下,顺便回顾学习windowSoftInputMode系列属性以及软键盘的相关知识。
windowSoftInputMode
下面是windowSoftInputMode的Documentation
Formats: flag
Values: adjustNothing, adjustPan, adjustResize, adjustUnspecified, stateAlwaysHidden, stateAlwaysVisible, stateHidden, stateUnchanged, stateUnspecified, stateVisible
Specify the default soft-input mode for the main window of this activity. A value besides "unspecified" here overrides any value in the theme.
我的英语知识小学级别的,哈哈……上面的大概意思呢,我认为就是说:这是一个标签,它可以取的值有这么多,我们可以从中选择设置一个值来控制当前这个活动窗口与软键盘之间的交互。既然是交互,这时就有两种状态,从这些values的命名也可以看出来,一种是窗口的,一种是软键盘的
window: adjustNothing, adjustPan, adjustResize, adjustUnspecified
softInput:stateAlwaysHidden, stateAlwaysVisible, stateHidden, stateUnchanged, stateUnspecified, stateVisible
它的设置必须是下面列表中的一个值,或一个 ”state…”值加一个 ”adjust…”值的组合。
值 | 作用 |
---|---|
adjustPan | 当显示软键盘时,调整window的空白区域来显示软键盘。软键盘还是有可能遮挡一些有内容区域,这时用户就只有退出软键盘才能看到这些被遮挡区域并进行交互。 |
adjustNothing | 当显示软键盘时,不调整window的布局 |
adjustResize | 当显示软键盘时,调整window内的控件大小以便显示软键盘。这样的话控件可能会变形。 |
adjustUnspecified | 不指定显示软件盘时,window的调整方式。系统去判断内容区域可滚动为adjustPan,不可滚动为adjustResize |
stateAlwaysHidden | 总是隐藏软键盘。 |
stateAlwaysVisible | 总是显示软键盘 |
stateHidden | 用户导航(navigate)到你的窗口的时候,隐藏软键盘 |
stateVisible | 用户导航(navigate)到你的窗口的时候,显示软键盘 |
stateUnchanged | 当这个activity出现时,软键盘将一直保持在上一个activity里的状态,无论是隐藏还是显示 |
stateUnspecified | 未指定软键盘的状态,系统将自动选择一个合适的状态或依赖于主题中的设置,这是默认的设置 |
软键盘显示和隐藏
正好前两天用到代码去设置软键盘的弹出与隐藏,也在此记录一下,因为显示与隐藏软件盘的方式都有多种,但是有的却是不起作用,下面是两种亲测可用的显示与隐藏方法
/**
* 隐藏软键盘
* @param view
*/
public static void hideSoftKeyboard() {
if (view == null || BaseApplication.getContext() == null)
return;
((InputMethodManager) BaseApplication.getContext().getSystemService(
Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(
view.getWindowToken(), 0);
}
/**
* 显示软键盘
*/
public static void showSoftKeyboard(){
((InputMethodManager) BaseApplication.getContext().getSystemService(
Context.INPUT_METHOD_SERVICE)).toggleSoftInput(0, InputMethodManager.RESULT_SHOWN);
}
以上,将知识顺了一遍;下面,来说说我今天是怎么爬坑的
我的布局如图所示,在AndroidManifest中进行设置该Activity:
-
windowSoftInputMode="adjustNothing"
这时,当软件盘弹出时,window不作调整,当页面向上滑动到顶时,下面有输入框,会被软键盘盖住 -
windowSoftInputMode="adjustPan"
这时,当软键盘弹出时,window调整页面显示,这个是调整空白区域,会自动将获取焦点的输入框滑动到弹出的软键盘上方,但是,当最下方的输入框,还是会被遮挡,这时window已经调整不了,并且页面向上滑动时,Toolbar也会被顶出屏幕 -
windowSoftInputMode="adjustResize"
- 这时,当软键盘弹出时,window调整页面显示,这个调整是调整整个页面的大小,比如,现在软键盘弹出,那么上面我这个页面,等于是整体往上压缩,下面挤出一个可以放下软键盘的区域,所以,就会把我下方的LinearLayout区域都挤上去,那么整个页面都变形了。
- 想办法:监听Scrollview的布局是否改变,判断它的bottom变大变小,将LinearLayout显示隐藏,想法是好的,但是,软键盘弹出,LinearLayout隐藏后,软键盘上方总是有一块和我布局下方LinearLayout同样大小的灰色区域,并且,当退出软键盘后,如果用的隐藏是VIEW.GONE的话,LinearLayout就回不来了
- 查找后,发现灰色区域原因出在我的Scrollview的布局属性weight=1上;至于设置成VIEW.GONE下方的LinearLayout再设置成VIEW.VISIBLE也回不来,不再显示,不明白,只能先用VIEW.VISIBLE属性
- 解决办法:
- windowSoftInputMode="adjustResize"
- 根布局修改为RelativeLayout,不再用weight属性,解决了软键盘上方灰色区域问题
//添加布局改变监听
scrollviewActorder.addOnLayoutChangeListener(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) {
LogUtil.ShowLog(bottom+"==="+oldBottom);
if (oldBottom>bottom) {
// 打开了软键盘,触发了界面resize
// 隐藏下方价格,按钮
LogUtil.ShowLog("size change ----------");
llBottom.setVisibility(View.INVISIBLE);
llBottom.setFocusable(false);
}else if(bottom>oldBottom){
llBottom.setVisibility(View.VISIBLE);
llBottom.setFocusable(true);
}
}
});
经过上面一系列的折腾,终于,将软键盘遮挡住输入框的问题完美解决。