Hide the Android navigation bar using WindowInsetsController
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
: