Search code examples
javaandroidandroid-navigation-bar

How to detect when the system navigation bar appears on full screen mode?


The following code successfully hides the system's navigation bar from the screen. Users can still swipe up to reveal the navigation bar, which will remain on screen for a few seconds, then disappear again.

Is there a callback to detect when the navigation bar appears and disappears, as the user swipes up, and afterwards, when the navigation bar automatically hides?

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {

    getWindow().setDecorFitsSystemWindows(false);

    if (getWindow().getInsetsController() != null) {
        getWindow().getInsetsController().hide(WindowInsets.Type.navigationBars());
        getWindow().getInsetsController().setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
    }

} else {

    getWindow().getDecorView().setSystemUiVisibility(
        View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
        View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
        View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
    );
}

The code below (taken from the docs) seems to detect when the navigation bar is hidden on launch, but not when the user swipes up to reveal it, or when it disappears afterwards.

View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
        (new View.OnSystemUiVisibilityChangeListener() {
    @Override
    public void onSystemUiVisibilityChange(int visibility) {
        // Note that system bars will only be "visible" if none of the
        // LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set.
        if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
            // TODO: The system bars are visible. Make any desired
            // adjustments to your UI, such as showing the action bar or
            // other navigational controls.
        } else {
            // TODO: The system bars are NOT visible. Make any desired
            // adjustments to your UI, such as hiding the action bar or
            // other navigational controls.
        }
    }
});

Solution

  • Is there a callback to detect when the navigation bar appears and disappears, as the user swipes up, and afterwards, when the navigation bar automatically hides?

    You can't detect that, a user's swipe to show the navigation bar or the status bar isn't a part of your app, it's the system responsibility that runs in a different process than your app's.

    Actually your app's window isn't affected on that swipe; and hence the bars are laid on top of your activity (without any extra insets) and that is an evidence that it's related to the system window instead. So, any listener within your app's process/window can't help on that.

    Check this answer for more detail.