转自 https://www.jianshu.com/p/4c7703361835
原理
软键盘弹出时,布局会进行调整,这时只要我们监听到跟布局的高度和可是区域的高度后,他们的差值就是软件盘的高度。要获取我们需要的条件要依靠这两位哥们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 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();
LogUtil.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;
}
@Override
protected void onDestroy() {
super.onDestroy();
//这里对监听器进行移除
if (softkeyListener != null){
findViewById(R.id.rl_main).getViewTreeObserver().removeOnGlobalLayoutListener(softkeyListener);
}
}
网友评论