Question

On Android 4 and up (excluding 4.4) when an app goes full screen (with SYSTEM_UI_FLAG_HIDE_NAVIGATION), then after the first touch the navigation bar appears (with software navigation keys). This means that all my layouts are moved up and have smaller sizes. This makes an ugly jump of all the layouts. Is there a way to make the navigation bar overlay my layout instead of pushing it up?

I want to make a video player with YouTube like behavior, where the navigation bar overlays the video after the touch so the video does not move up and shrinks a bit, which is annoying. System/status bar is not a problem, just the navigation bar. Thank you.

Was it helpful?

Solution

Forget on my previously answer not working on all versions. The right approach is to find out navigation bar height and add bottom margin -navigationBarHeight. This is full working example work on all 4.1+ versions:

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

@SuppressLint("NewApi")
private int getRealScreenSize(boolean returnWidth) {

    final DisplayMetrics metrics = new DisplayMetrics();
    Display display = getActivity().getWindowManager().getDefaultDisplay();
    Method mGetRawH = null, mGetRawW = null;

    //Not real dimensions
    display.getMetrics(metrics);
    int width = metrics.heightPixels;
    int height = metrics.widthPixels;

    try {
        // For JellyBeans and onward
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
            display.getRealMetrics(metrics);

            //Real dimensions
            width = metrics.heightPixels;
            height = metrics.widthPixels;
        } else {
            mGetRawH = Display.class.getMethod("getRawHeight");
            mGetRawW = Display.class.getMethod("getRawWidth");

            try {
                width = (Integer) mGetRawW.invoke(display);
                height = (Integer) mGetRawH.invoke(display);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    } catch (NoSuchMethodException e3) {
        e3.printStackTrace();
    }

    if (returnWidth) {
        return width;
    } else {
        return height;
    }
}

Following example code need to put somewhere after surface was created:

RelativeLayout.LayoutParams lp = (LayoutParams) surfaceView.getLayoutParams();
int screenHeight = getRealScreenSize(false);
int screenWidth = getRealScreenSize(true);
int navigationBarHeight = getNavigationBarHeight(getActivity());
lp.height = (int) (screenWidth / (16d / 9d));
lp.width = screenWidth;
int k = (lp.height - screenHeight) / 2;
lp.setMargins(0, -k, 0, (-k) - navigationBarHeight);
surfaceView.setLayoutParams(lp);

Note that surface view must have parent RelativeLayout.

OTHER TIPS

This works, need to put onCreate():

WindowManager.LayoutParams attributes = getWindow().getAttributes();
attributes.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
getWindow().setAttributes(attributes);

More info you can find on link: http://www.thekirankumar.com/blog/2013/02/10/show-and-hide-android-notification-bar-without-causing-a-layout-jerk/

In below links there have written details about working with " System UI " & " Work with SYSTEM_UI_FLAG_LOW_PROFILE , SYSTEM_UI_FLAG_VISIBLE & SYSTEM_UI_FLAG_HIDE_NAVIGATION" :

http://developer.android.com/about/versions/android-4.0.html#SystemUI https://developer.android.com/reference/android/view/View.html#setSystemUiVisibility(int) https://developer.android.com/reference/android/view/View.html#SYSTEM_UI_FLAG_HIDE_NAVIGATION

I believe another nice question about " Hide System Bar " with some nice answers :

Hide System Bar in Tablets

Hope these will help you to get your work done.

Happy coding !!!

View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(uiOptions);

Those flags make system and navigation bars overlay your content

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top