9

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!

Florent Anders
  • 630
  • 2
  • 7
  • 25
  • What are you trying to achieve? Shed some details about that. Probably you don't need to calculate navigation bar height at all. – shaktiman_droid Apr 09 '16 at 07:55
  • @Jabbar_Jigariyo I need to set a padding to a bottom view containing ImageButtons and more when the user has a navigation bar (I'm using the transparent navigation bar) – Florent Anders Apr 09 '16 at 07:57
  • If you're using transparent nav bar then why would be a need of hiding it ? For those devices which has nav bar, it would be already transparent and for those devices which has physical button, there would be no nav bar. Right ? – shaktiman_droid Apr 09 '16 at 08:03
  • I assume you're using `android:windowTranslucentNavigation` in your `Theme` – shaktiman_droid Apr 09 '16 at 08:03
  • @Jabbar_Jigariyo The HTC One A9 has a fingerprint sensor that works as a home button. And yes, I am – Florent Anders Apr 09 '16 at 08:12
  • Check the solution on [link](http://stackoverflow.com/questions/20264268/how-to-get-height-and-width-of-navigation-bar-programmatically) – Anirudh Loya Apr 09 '16 at 11:17
  • Possible duplicate of [How to get height and width of navigation bar programmatically](http://stackoverflow.com/questions/20264268/how-to-get-height-and-width-of-navigation-bar-programmatically) – Sufian May 03 '17 at 11:40

3 Answers3

11

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.

Community
  • 1
  • 1
ToinToin
  • 174
  • 2
  • 7
0

Use following code to get Navigation bar. However, you need to consider Multi window mode as well as whether Navigation bar is at the bottom or on left side or right side of the window.

getNavigationBarHeight(){
    Resources resources = context.getResources();
    int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
    if (resourceId > 0) {
        return resources.getDimensionPixelSize(resourceId);
    }
    return 0;
}
mayank1513
  • 4,971
  • 3
  • 23
  • 70
0
    fun Context.isSoftNavigationBarAvailable(): Boolean {
        val navBarInteractionModeId = resources.getIdentifier(
                  "config_navBarInteractionMode",
                  "integer",
                  "android"
        )
        if (navBarInteractionModeId > 0 && resources.getInteger(navBarInteractionModeId) > 0) {
            // nav gesture is enabled in the settings
            return false
        }
        val appUsableScreenSize = Point()
        val realScreenSize = Point()
        val defaultDisplay = (getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay
        defaultDisplay.getSize(appUsableScreenSize)
        defaultDisplay.getRealSize(realScreenSize)
        return appUsableScreenSize.y < realScreenSize.y }