0

I am trying to add a bottom padding to the screen (or the elements on the screen) when the software bottom navigation buttons are present on the device (Back, Home, Menu). However, it looks like there is no 100% accurate method on getting the height.

What I have tried is following:

  var androidApp = Application.android;
  var context = Utility.ad.getApplicationContext();
  var resources = context.getResources();

  var resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
  if (resourceId > 0) {
    console.log(resources.getDimensionPixelSize(resourceId))
  }

But this seems to always return some value - 126 (both on emulator and a real device with configurable show on / off software buttons, otherwise hardware buttons)). As many answers on SO have confirmed, this solution does not work for HTC, OnePlus and few other devices.

What I would like to try next is this answer - How to get height and width of navigation bar programmatically. Unfortunately, I am struggling to transpile this to Nativescript.


Answer:

I get navigation bar size by comparing app-usable screen size with real screen size. I assume that navigation bar is present when app-usable screen size is smaller than real screen size. Then I calculate navigation bar size. This method works with API 14 and up.

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;
}

I am using NS3, Angular 4 and have no clue about Java or Nativescript programming :)

Any ideas on both how to achive this and how to transpile the code (if you think that is the best option)?

nbo
  • 409
  • 4
  • 17

1 Answers1

0

I transpiled given code in typescript:

var app = require("application");
declare var android:any;

export function getNavigationBarSize() {
    let context = app.android.context;
    let appUsableSize = getAppUsableScreenSize();
    let realScreenSize = getRealScreenSize();

    // navigation bar on the right
    // I dont care about right nav bar, so i return 0
    if (appUsableSize.x < realScreenSize.x) {
        return 0; // new android.graphics.Point(realScreenSize.x - appUsableSize.x, appUsableSize.y);
    }

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

    // navigation bar is not present
    return 0; //new android.graphics.Point();
}

export function getAppUsableScreenSize() {
    let context = app.android.context;
    let windowManager = context.getSystemService(android.content.Context.WINDOW_SERVICE);
    let display = windowManager.getDefaultDisplay();
    let size = new android.graphics.Point();
    display.getSize(size);
    return size;
}

export function getRealScreenSize() {
    let context = app.android.context;
    let windowManager = context.getSystemService(android.content.Context.WINDOW_SERVICE);
    let display = windowManager.getDefaultDisplay();
    let size = new android.graphics.Point();

    if (android.os.Build.VERSION.SDK_INT >= 17) {
        display.getRealSize(size);
    } else if (android.os.Build.VERSION.SDK_INT >= 14) {
        try {
            size.x = android.view.Display.class.getMethod("getRawWidth").invoke(display);
            size.y = android.view.Display.class.getMethod("getRawHeight").invoke(display);
        } catch (e) {
            console.log(e);
            console.log(e.stack);
        }
    }
    return size;
}

And then I used to check the real display height:

import platform = require("tns-core-modules/platform");

let navHeight = getNavigationBarSize() / platform.screen.mainScreen.scale;
let usableHeight = platform.screen.mainScreen.heightDIPs - navHeight;
Andrea Pinti
  • 121
  • 3