轉自 http://www.lxweimin.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);
}
}