Android 獲取軟鍵盤和狀態欄以及底部導航欄高度

windowSoftInputMode屬性釋義
  1. adjustPan屬性:假如鍵盤彈出後遮擋住了EditText控件,該控件獲取焦點之後,整個DecorView會向上整體移動(也就是標題欄和內容欄),直到EditText控件出現在鍵盤的正上方位置.
  2. adjustResize屬性:假如鍵盤彈出後遮擋住了EditText控件,該控件獲取焦點之後,DecorView中的內容欄中(就是id=android.R.id.content)子View(就是自己定義的佈局,但該佈局最外層必須是ScrollView,否則不會移動)會向上移動,直到EditText控件出現在鍵盤的正上方位置.而標題欄不會移動.
  3. adjustNothing屬性:假如鍵盤彈出後遮擋住了EditText控件,該控件獲取焦點之後依舊會被鍵盤遮住.
  • 例子
<activity
    android:name=".MainActivity"
    android:windowSoftInputMode="adjustPan"/>
獲取狀態欄與底部導航欄高度
  • 通常情況獲取狀態欄高度
public static int getStatusBarHeight() {
    Resources resources = Resources.getSystem();
    int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
    return resources.getDimensionPixelSize(resourceId);
}
  • 通常情況獲取底部導航欄高度
  1. 有些手機比如Galaxy J3 Pro,沒有底部導航欄依舊能用下面的方法獲取導航欄高度.
private static int getNavBarHeight() {
    Resources res = Resources.getSystem();
    int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
    if (resourceId != 0) {
        return res.getDimensionPixelSize(resourceId);
    } else {
        return 0;
    }
}
  • 另外一種方法獲取導航欄與狀態欄高度
  1. 該方法需要在onResume(),onCreate()生命週期方法中調用,避免軟鍵盤升起後調用.
int mNvaHeight;
int mSBHeight;
public void getNavAndSbHeight() {
    final View mDecorView = this.getWindow().getDecorView();
    mDecorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            // 屏幕高度
            int screenHeight = ScreenUtils.getScreenHeight(MainActivity.this);
            Rect rect = new Rect();
            // Window可視區域座標(不包含狀態欄與底部導航欄高度)
            mDecorView.getWindowVisibleDisplayFrame(rect);
            // 獲取底部導航欄高度.
            mNvaHeight = Math.abs(screenHeight - rect.bottom);
            // 頂部狀態欄高度.
            mSBHeight = rect.top;
            Log.e(TAG, "該Activity界面底部導航欄高度  " + mNvaHeight[0] + " 頂部狀態欄高度 " + mNvaHeight[1]);
            mDecorView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
    });
}
獲取軟鍵盤高度
  • mDecorView.getBottom()該方法獲取DecorView.bottom座標不穩定,所以不能用該值來獲取軟鍵盤高度.
  1. 在華爲PE-TL20上導航欄顯示時獲取的值不包含導航欄高度.
  2. 在OPPO A3s上獲取的值是包含導航欄高度的.
  • 該方法需要在軟鍵盤升起時候調用才能獲取鍵盤高度.
int mNavSize;
public int getSoftInputHeight() {
    int mSoftInputHeight;
    int mScreenHeight = ScreenUtils.getScreenHeight(this);
    final View mDecorView = this.getWindow().getDecorView();
    Rect rect = new Rect();
    // Window可視區域座標(不包含狀態欄與底部導航欄高度,此時軟鍵盤已經升起)
    mDecorView.getWindowVisibleDisplayFrame(rect);
    // 不建議用這種方式獲取軟鍵盤高度
    // int mDecorViewBottom = mDecorView.getBottom();
    // int mSoftInputHeight = Math.abs(mDecorViewBottom - rect.bottom);
    int diffSize = Math.abs(mScreenHeight - rect.bottom);
    if (mNavSize > 0) {
        // 如果導航欄可見
        mSoftInputHeight = diffSize - mNavSize;
    } else {
        // 如果導航欄不可見
        mSoftInputHeight = diffSize;
    }
    return mSoftInputHeight;
}
  • 屏幕工具類
public final class ScreenUtils {
    /**
     * Return the width of screen, in pixel.
     *
     * @return the width of screen, in pixel
     */
    public static int getScreenWidth(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        if (wm == null) return -1;
        Point point = new Point();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            wm.getDefaultDisplay().getRealSize(point);
        } else {
            wm.getDefaultDisplay().getSize(point);
        }
        return point.x;
    }
    /**
     * Return the height of screen, in pixel.
     *
     * @return the height of screen, in pixel
     */
    public static int getScreenHeight(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        if (wm == null) return -1;
        Point point = new Point();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            wm.getDefaultDisplay().getRealSize(point);
        } else {
            wm.getDefaultDisplay().getSize(point);
        }
        return point.y;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章