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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章