WindowInsetsController#hide(statusBars()) causes content to jump

3.5k Views Asked by At

At the moment my activity calls

requestWindowFeature(Window.FEATURE_NO_TITLE)
window.setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN)

inside of its onCreate method in order to hide the status bar and display in fullscreen mode.

As part of the migration to Android 30 I replace window.setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN) with WindowInsetsController#hide(statusBars()) as documentation suggests. However, the behaviour of these two approaches is not the same. While the deprecated one smoothly hides the status bar the modern one makes the content of the activity to "jump" when the status bar is hidden.

Has anybody observed the same behaviour and found a fix for it?

2

There are 2 best solutions below

2
flauschtrud On

I'm not sure if it fits your specific purpose since I had to rework my code a lot for a satisfactory solution, but I managed to get rid of the "jumping" with the following code in my Activity (I use the Compat classes to avoid having to code multiple implementations, but the original classes work the same):

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (hasFocus) {
        hideSystemUI();
    }
}

private void hideSystemUI() {
    WindowCompat.setDecorFitsSystemWindows(getWindow(), false);

    WindowInsetsControllerCompat insetsController =   WindowCompat.getInsetsController(getWindow(), getWindow().getDecorView());
    if (insetsController != null) {
        insetsController.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
        insetsController.hide(WindowInsetsCompat.Type.statusBars());
        insetsController.hide(WindowInsetsCompat.Type.navigationBars());
    }
}

I had a toggling solution before which showed the system and navigation bar on touch (quite similar to the now deprecated documentation, but I was not able to make it work without jumping.

What made the difference for me was to use WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE. The documentation about this option says the following:

These transient system bars will overlay app’s content, may have some degree of transparency, and will automatically hide after a short timeout.

By the way, since the official documentation still uses deprecated code as of today I marked it as "unusable documentation" down below in the hope that it will get updated sooner.

0
Renzo Sampietro On

Kotlin version used in my app

`

private fun setToFullScreen() {
    WindowCompat.setDecorFitsSystemWindows(window, false)

    val insetsController = WindowCompat.getInsetsController(window, window.decorView)
    insetsController.systemBarsBehavior =
            WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
    insetsController.hide(WindowInsetsCompat.Type.statusBars())
    insetsController.hide(WindowInsetsCompat.Type.navigationBars())
}

`