在项目中经常有实现 软键盘的弹出、关闭、监听软键盘、软键盘顶起输入框 的功能。所以稍微整理一下
一、软键盘影响顶起输入框
要想让输入框不被遮住,那么就要在清单文件中activity组件下设置windowSoftInputMethod功能。有很多文章也都说过,不过只是把官网文档copy一下,我这里做了调研,得到如下结论:
假设有Activity A B C ,B含一个edittext
statevisible:
当从A跳到B时B软件盘会弹起,当从B跳到C然后返回B的时候,软键盘不会弹起。它和StateAlwaysVisible区别是:后者当页面进入B时软件盘总是展示的。
stateHiden和stateAlwaysHidden:
同上规则相同。
adjustPan:
在任何情况下,点击输入框键盘弹出,平移窗口内容,actionBar也会被平移。使用简单但有局限性
adjustResize:
1.当有scrollView或listview、recyclerview等可滚动的view时,可滚动的view会调整尺寸为软键盘让出空间
2.顶级view为RelativeLayout且有控件有属性aliginParentBottom。该控件会调整尺寸为软键盘让出空间
3.当使用透明状态栏的情况下,如果fitSystemWindow=true,可以让出空间(fitSystemWindow表示是否腾出系统空间,比如软键盘和状态栏)。
非以上三种情况,设置该属性无效。因为在有可滚动view和aliginparentBottom的时候,去调整内容空间大小才会影响到子控件位置变化
二、监听软键盘状态
a.在windowSoftInputMethod为adjustResize且不为全屏的情况下可以通过计算根view和DecorView的高度差来判断,有两种方式
1.重写OnMesure
public class KeyboardAwareLinearLayout extends LinearLayout {
public KeyboardAwareLinearLayout(Context context) {
super(context);
}
public KeyboardAwareLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public KeyboardAwareLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int proposedHeight = MeasureSpec.getSize(heightMeasureSpec);
final int actualHeight = getHeight();
if (actualHeight > proposedHeight) {
Log.e("keyboard", "guess keyboard is shown");
} else {
Log.e("keyboard", "guess keyboard has been hidden");
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
2.rootView的GlobleLayout监听
private boolean mKeyboardUp;
private void setListenerToRootView() {
final View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final int headerHeight = getActionBarHeight() + getStatusBarHeight();
int heightDiff = rootView.getRootView().getHeight() - rootView.getHeight();
if (heightDiff > headerHeight) {
Log.e("keyboard", "keyboard is up");
if (!mKeyboardUp) {
mKeyboardUp = true;
}
} else if (mOpen) {
Log.e("keyboard", "keyboard is hidden");
mKeyboardUp = false;
}
}
});
}
b.在windowSoftInputMethod为adjustResize或adjustPan的时候可以通过计算viewRoot的底部间隙
private boolean isKeyboardShown(View rootView) {
final int softKeyboardHeight = 100;
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
int heightDiff = rootView.getBottom() - r.bottom;
return heightDiff > softKeyboardHeight * dm.density;
}
三、软键盘的关闭、隐藏 、展示
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
// 获取软键盘的显示状态
boolean isOpen=imm.isActive();
// 如果软键盘已经显示,则隐藏,反之则显示
imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
// 隐藏软键盘
imm.hideSoftInputFromWindow(view, InputMethodManager.HIDE_NOT_ALWAYS);
// 强制显示软键盘
imm.showSoftInput(view,InputMethodManager.SHOW_FORCED);
// 强制隐藏软键盘
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
参考:http://blog.csdn.net/doris_d/article/details/52536480