Introduction

Documentation describing how to hide the navigation bar and/or running an Android application in fullscreen usually uses the View.SYSTEM_UI_FLAG_HIDE_NAVIGATION and View.SYSTEM_UI_FLAG_FULLSCREEN flags, e.g. Android developer documents and a another Android developer doc.

However SYSTEM_UI_FLAG_FULLSCREEN and SYSTEM_UI_FLAG_HIDE_NAVIGATION are marked deprecated together with the other SYSTEM_UI-flags. This note describes how to hide navigation bar in the new way using the WindowInsetsController.

Example

There is a working demo/test written in Kotlin of WindowInsetsController on my github

Fullscreen mode

The WindowInsetController class have methods that is supposed to replace the use of the deprecated SYSTEM_UI_FLAG_FULLSCREEN, however the methods used for hiding the bars are only available in Android 11 and newer (i.e. API Level > 30). This is solved by using the wrapper class WindowInsetsControllerCompat who will handle checking the API-level of the device running the application and make it work for all API-levels.

For fullscreen, hide the navigation and status bars.

WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(getWindow(), getWindow().getDecorView());
controller.hide(WindowInsetsCompat.Type.systemBars());

To allow the bars to be shown when swiping from the edge of the screen one can set system bars behaviour like this:

controller.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);

Making your own transient navigation bar

Under some circumstances the navigation bar did not show up when swiping from the edge of the screen on my application. Unsure why it happened but it was often the case after the screen was rotated.

I made a workaround to show the navigation bar when tapping on the screen instead.

Show the navigation bar for 3s when tapping on the layout:

mainlayout.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        View decorView = getWindow().getDecorView();
        WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(getWindow(), decorView);
        controller.show(WindowInsetsCompat.Type.navigationBars());
        decorView.postDelayed(new Runnable() {
            @Override
            public void run() {
                controller.hide(WindowInsetsCompat.Type.systemBars());
            }
        }, 3000);
    }
});

Note that the above is an example and it may not be possible to use the main layout for capturing the click events.

Translucent Navigation bar

When the Navigation bar is auto-hiding it looks nice if it also is made translucent. Add the following to the style element in themes.xml (or the resource file containing the style e.g. style.xml)

    <item name="android:windowTranslucentNavigation">true</item>
    <item name="android:fitsSystemWindows">true</item>

The second line is needed in order to make the activity content display correct. Without it some parts of the content may be laid out outside of the screen like this:

Compared to when using a translucent navigation bar and fitsSystemWindows: true:

Resources

Exploring WindowInsets on Android 11