Android软键盘监听
开发中我们可能需要对软键盘进行监听,比如登陆页面,当软键盘抬起的时候,会将输入密码和登录按钮给遮挡住,用户输入完账号后得先按下软键盘再点击密码进行输入,体验很差,如下:

而我们想要如下效果:

~这就需要针对软件盘做一些操作了~
二、自定义监听软件盘的布局
public class KeyboardLayout extends RelativeLayout {
private onSizeChangedListener mChangedListener;
private static final String TAG = "KeyboardLayoutTAG";
private boolean mShowKeyboard = false;
public KeyboardLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
public KeyboardLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public KeyboardLayout(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
Log.d(TAG, "onMeasure-----------");
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
super.onLayout(changed, l, t, r, b);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// TODO Auto-generated method stub
super.onSizeChanged(w, h, oldw, oldh);
if (null != mChangedListener && 0 != oldw && 0 != oldh) {
if (h < oldh) {
mShowKeyboard = true;
} else {
mShowKeyboard = false;
}
mChangedListener.onChanged(mShowKeyboard);
}
}
public void setOnSizeChangedListener(onSizeChangedListener listener) {
mChangedListener = listener;
}
public interface onSizeChangedListener {
void onChanged(boolean showKeyboard);
}
}
三、布局文件使用我们自定义的布局,将其放入根节点:
四、还需要写一个类,是对软键盘adjustResize属性的修复
public class AndroidAdjustResizeBugFix {
private View mChildOfContent;
private int usableHeightPrevious;
private int statusBarHeight;
private FrameLayout.LayoutParams frameLayoutParams;
private Activity mActivity;
private AndroidAdjustResizeBugFix(Activity activity) {
mActivity = activity;
FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
mChildOfContent = content.getChildAt(0);
statusBarHeight = getStatusBarHeight();
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
possiblyResizeChildOfContent();
}
});
frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
}
public static void assistActivity(Activity activity) {
new AndroidAdjustResizeBugFix(activity);
}
private void possiblyResizeChildOfContent() {
int usableHeightNow = computeUsableHeight();
if (usableHeightNow != usableHeightPrevious) {
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
if (heightDifference > (usableHeightSansKeyboard / 4)) {
// keyboard probably just became visible
// 如果有高度变化,mChildOfContent.requestLayout()之后界面才会重新测量
// 这里就随便让原来的高度减去了1
frameLayoutParams.height = usableHeightSansKeyboard - 1;
} else {
// keyboard probably just became hidden
frameLayoutParams.height = usableHeightSansKeyboard;
}
mChildOfContent.requestLayout();
usableHeightPrevious = usableHeightNow;
}
}
private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
return r.bottom - r.top + statusBarHeight;
}
private int getStatusBarHeight() {
try {
Class<?> c = Class.forName("com.android.internal.R$dimen");
Object obj = c.newInstance();
Field field = c.getField("status_bar_height");
int x = Integer.parseInt(field.get(obj).toString());
int dimensionPixelSize = mActivity.getResources().getDimensionPixelSize(x);
return dimensionPixelSize;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
}
五、在当前activity的oncreate方法中加入 AndroidAdjustResizeBugFix.assistActivity(this);
给我们自定义的布局添加软键盘监听
mRootView.setOnSizeChangedListener(new KeyboardLayout.onSizeChangedListener() {
@Override
public void onChanged(boolean showKeyboard) {
if (showKeyboard) {
mHandler.sendMessage(mHandler.obtainMessage(KEYBOARD_SHOW));
} else {
mHandler.sendMessage(mHandler.obtainMessage(KEYBOARD_HIDE));
}
}
});
然后在Handler中进行后续操作
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case KEYBOARD_HIDE:
mContentView.setPadding(0, 0, 0, 0);
break;
case KEYBOARD_SHOW:
//mContentView.setPadding(0,"需要移动的距离",0,0);
break;
default:
break;
}
}
};