原理
软键盘弹出时,布局会进行调整,这时只要我们监听到跟布局的高度和可是区域的高度后,他们的差值就是软件盘的高度。要获取我们需要的条件要依靠这两位哥们ViewTreeObserver.OnGlobalLayoutListener
和getWindowVisibleDisplayFrame(rect)
OnGlobalLayoutListener
是ViewTreeObserver
的内部类,当一个视图树的布局发生改变时,可以被ViewTreeObserver
监听到,这是一个注册监听视图树的观察者(observer),在视图树的全局事件改变时得到通知。我们通过OnGlobalLayoutListener
监听布局变化通知,这样我们就可以间接的监听到软键盘的动态。getWindowVisibleDisplayFrame(rect)可以获取到程序显示的区域,包括标题栏,但不包括状态栏,获取后的区域坐标会保存在
rect
(Rect类型)中。软键盘的高度
height=rootView.getRootView().getHeight()-rect.bottom;
rootView是xml的根布局
Activity的android:windowSoftInputMode="adjustNothing",这种模式会失效,其他模式都可,推荐使用
adjustResize
。
福利区
private static boolean isFirst = true;
public interface OnGetSoftHeightListener {
void onShowed(int height);
}
public interface OnSoftKeyWordShowListener {
void hasShow(boolean isShow);
}
/** * 获取软键盘的高度 * *
@param rootView *
@param listener
*/
public static void getSoftKeyboardHeight(final View rootView, final OnGetSoftHeightListener listener) {
final ViewTreeObserver.OnGlobalLayoutListener layoutListener
= new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (isFirst) {
final Rect rect = new Rect();
rootView.getWindowVisibleDisplayFrame(rect);
final int screenHeight = rootView.getRootView().getHeight();
final int heightDifference = screenHeight - rect.bottom;
//设置一个阀值来判断软键盘是否弹出
boolean visible = heightDifference > screenHeight / 3;
if (visible) {
isFirst = false;
if (listener != null) {
listener.onShowed(heightDifference);
}
rootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
}
};
rootView.getViewTreeObserver().addOnGlobalLayoutListener(layoutListener);
}
/** * 判断软键盘是否弹出
* * @param rootView
* @param listener
*备注:在不用的时候记得移除OnGlobalLayoutListener
*/
public static ViewTreeObserver.OnGlobalLayoutListener doMonitorSoftKeyWord(final View rootView, final OnSoftKeyWordShowListener listener) {
final ViewTreeObserver.OnGlobalLayoutListener layoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final Rect rect = new Rect();
rootView.getWindowVisibleDisplayFrame(rect);
final int screenHeight = rootView.getRootView().getHeight();
Log.e("TAG",rect.bottom+"#"+screenHeight);
final int heightDifference = screenHeight - rect.bottom;
boolean visible = heightDifference > screenHeight / 3;
if (listener != null)
listener.hasShow(visible);
}
};
rootView.getViewTreeObserver().addOnGlobalLayoutListener(layoutListener);
return layoutListener;
}