How to REALLY get the navigation bar height in And

2019-05-07 10:01发布

问题:

I own a HTC One A9 which has the ability to hide the navigation bar. In my app, I need to get the height of the navigation bar and set a padding corresponding to it. Here's my problem now: When I hide the navigation bar, the padding is still being set (even Snapchat has this problem). My question is: Is there alternative code to this one that makes it work?

public static int getNavBarHeight(Context context) {
    int result = 0;
    int resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = context.getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

Thanks for your help!

回答1:

This is the code I use to get the navigation bar size. Its height will be in Point.y

Credit to this answer

public static Point getNavigationBarSize(Context context) {
    Point appUsableSize = getAppUsableScreenSize(context);
    Point realScreenSize = getRealScreenSize(context);

    // navigation bar on the right
    if (appUsableSize.x < realScreenSize.x) {
        return new Point(realScreenSize.x - appUsableSize.x, appUsableSize.y);
    }

    // navigation bar at the bottom
    if (appUsableSize.y < realScreenSize.y) {
        return new Point(appUsableSize.x, realScreenSize.y - appUsableSize.y);
    }

    // navigation bar is not present
    return new Point();
}

public static Point getAppUsableScreenSize(Context context) {
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = windowManager.getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    return size;
}

public static Point getRealScreenSize(Context context) {
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = windowManager.getDefaultDisplay();
    Point size = new Point();

    if (Build.VERSION.SDK_INT >= 17) {
        display.getRealSize(size);
    } else if (Build.VERSION.SDK_INT >= 14) {
        try {
            size.x = (Integer)     Display.class.getMethod("getRawWidth").invoke(display);
            size.y = (Integer) Display.class.getMethod("getRawHeight").invoke(display);
    } catch (IllegalAccessException e) {} catch     (InvocationTargetException e) {} catch (NoSuchMethodException e) {}
    }

    return size;
}

Edit: To answer your question I had to use this function since I wanted to add ResideMenu to my app, but ended getting a weird empty margin at the bottom of my app, because of the navigation bar.

So I edited this function added by ResideMenu like this:

@Override
protected boolean fitSystemWindows(Rect insets) {
    // Applies the content insets to the view's padding, consuming that content (modifying the insets to be 0),
    // and returning true. This behavior is off by default and can be enabled through setFitsSystemWindows(boolean)
    // in API14+ devices.

    int bottomPadding = insets.bottom;

    Point p = getNavigationBarSize(getContext());

    if (Build.VERSION.SDK_INT >= 21 && p.x != 0) {
        Resources resources = getContext().getResources();
        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId > 0) {
            bottomPadding += resources.getDimensionPixelSize(resourceId);
        }
    }

    this.setPadding(viewActivity.getPaddingLeft() + insets.left, viewActivity.getPaddingTop() + insets.top,
            viewActivity.getPaddingRight() + insets.right, viewActivity.getPaddingBottom() + bottomPadding);
    insets.left = insets.top = insets.right = insets.bottom = 0;
    return true;
}

Hope that will help you.