Android 屏幕高度获取

138 阅读1分钟

常见的屏幕高度获取API

获取metrics中的高度值

private fun getScreenHeight(context: Context): Int {
    return context.resources?.displayMetrics?.heightPixels ?: 0
}
private fun getScreenHeight(context: Context): Int {
    //Display屏幕显示的详细信息
    val display = windowManager.getDefaultDisplay()
    //从Display获取DisplayMetrics信息
    val metrics = DisplayMetrics()
    display.getMetrics(metrics)
    return metrics.heightPixels
}

看一下displayMetrics里面是什么

{
    density=4.0, 
    width=1440, 
    height=3036, 
    scaledDensity=4.0, 
    xdpi=571.5, 
    ydpi=564.444
 }

通过这种方式,获取到的屏幕高度,不包括顶部状态栏底部导航栏的高度

windowManager获取display的realSize

public static int getRealHeight(Context context) {
    final DisplayMetrics metrics = new DisplayMetrics();
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    Method mGetRawH = null;
    int realHeight = -1;
    try {
        // For JellyBeans and onward
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {

            display.getRealMetrics(metrics);
            realHeight = metrics.heightPixels;
        } else {
            // Below Jellybeans you can use reflection method
            mGetRawH = Display.class.getMethod("getRawHeight");
            try {
                realHeight = (Integer) mGetRawH.invoke(display);
            } catch (IllegalArgumentException e) {
               Log.e(TAG, e.getMessage());
            } catch (IllegalAccessException e) {
               Log.e(TAG, e.getMessage());
            } catch (InvocationTargetException e) {
               Log.e(TAG, e.getMessage());
            }
        }
    } catch (NoSuchMethodException e) {
        Log.e(TAG, e.getMessage());
    }
    return realHeight;
}

通过这种方式,获取到的屏幕高度,包括顶部状态栏底部导航栏的高度

兼容问题

部分机型 通过getScreenHeight()获取到的屏幕高度 均包括了顶部状态栏的值

获取底部导航栏高度

public static int getNavigationBarHeight(Context context) {
    Resources res = context.getResources();
    int result = 0;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        String key;
        if (mInPortrait) { // 是否竖屏
            key = "navigation_bar_height";
        } else {
            key = "navigation_bar_height_landscape";
        }
        return getInternalDimensionSize(res, key);
    }
    return result;
}

private static int getInternalDimensionSize(Resources res, String key) {
    int result = 0;
    int resourceId = res.getIdentifier(key, "dimen", "android");
    if (resourceId > 0) {
        result = res.getDimensionPixelSize(resourceId);
    }
    return result;
}

兼容问题

  1. 设置隐藏导航栏后,返回也不一定为0,不同厂商型号手机返回有差异

获取顶部状态栏高度

fun getStatusBarHeight(context: Context): Int {
    var result = 0
    val resources = context.resources
    val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
    if (resourceId > 0) {
        result = resources.getDimensionPixelSize(resourceId)
    }
    return result
}

兼容问题

修改应用dpi值后,需要处理顶部状态栏的字体展示

实践

samsung 1440 x 3200