Overflow Menu click disabling Immersive mode - Android 4.4 Kitkat
Asked Answered
D

4

7

Anybody know if this is a Bug or is supposed to do this. When clicking the Overflow icon while using KitKat's Immersive mode, it disables the immersive mode. Anybody else running into this?

Full Code by Google - Here

public void toggleHideyBar() {

    // The UI options currently enabled are represented by a bitfield.
    // getSystemUiVisibility() gives us that bitfield.
    int uiOptions = getActivity().getWindow().getDecorView().getSystemUiVisibility();
    int newUiOptions = uiOptions;
    boolean isImmersiveModeEnabled =
            ((uiOptions | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) == uiOptions);
    if (isImmersiveModeEnabled) {
        Log.i(TAG, "Turning immersive mode mode off. ");
    } else {
        Log.i(TAG, "Turning immersive mode mode on.");
    }

    // Navigation bar hiding:  Backwards compatible to ICS.
    if (Build.VERSION.SDK_INT >= 14) {
        newUiOptions ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
    }

    // Status bar hiding: Backwards compatible to Jellybean
    if (Build.VERSION.SDK_INT >= 16) {
        newUiOptions ^= View.SYSTEM_UI_FLAG_FULLSCREEN;
    }

    // Immersive mode: Backward compatible to KitKat.
    // Note that this flag doesn't do anything by itself, it only augments the behavior
    // of HIDE_NAVIGATION and FLAG_FULLSCREEN.  For the purposes of this sample
    // all three flags are being toggled together.
    // Note that there are two immersive mode UI flags, one of which is referred to as "sticky".
    // Sticky immersive mode differs in that it makes the navigation and status bars
    // semi-transparent, and the UI flag does not get cleared when the user interacts with
    // the screen.
    if (Build.VERSION.SDK_INT >= 18) {
        newUiOptions ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
    }

    getActivity().getWindow().getDecorView().setSystemUiVisibility(newUiOptions);
}
Decastere answered 4/12, 2013 at 1:59 Comment(0)
T
3

In K, the overflow menu is a separate window that takes focus, and therefore drives the current system UI flags.

However, this only comes up if you are trying to show the action bar when the status bar is hidden, which is discouraged. For contextual menus outside of the action bar, you can use PopupWindow instead (with PopupWindow you can set the system UI flags yourself as needed).

Tabb answered 17/12, 2013 at 16:44 Comment(4)
Thanks for the info, This is exactly what is happening to me. I am using the ActionBar still because my app consists of WebView and i need to have back, forward, and refresh buttons available. I will look into the PopUp Window for the solution.Decastere
Strange, my PopupWindow is dropping me out of immersion mode as wellBaryon
With PopupWindow, you control the contents - so you can set the system UI flags for that window as needed.Tabb
I'm wondering: since PopupWindow has no getWindow method, how can you access the window of the popup and set the system UI flags on it?Psychoneurotic
L
2

I am not clear on how to set the system UI flags for the PopupWindow. I tried something like this:

PopupMenu popupMenu = new PopupMenu(mainHandle, view) {
   @Override
   public void show() {
       getWindow().getDecorView().setSystemUiVisibility(
           View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
           View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
           View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
           View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
           View.SYSTEM_UI_FLAG_FULLSCREEN |
           View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
       super.show();
}
Lanitalank answered 24/4, 2015 at 22:16 Comment(0)
B
0

Here's a workaround in Kotlin that enables immersive mode back when the ActionBar popup menu is dismissed:

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    supportActionBar!!.addOnMenuVisibilityListener { isVisible ->
        if (!isVisible) enableImmersiveMode()
    }
    ...
}

@SuppressLint("InlinedApi")
private fun enableImmersiveMode() {
    window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
            View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
            View.SYSTEM_UI_FLAG_FULLSCREEN or
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
}
Beebeebe answered 1/12, 2017 at 21:36 Comment(0)
G
0

Something that worked well for me - hopefully this will help those who come back to this in the future.

You can use a Handler to change the flags after the overflow menu appears. On my devices, the back button still appears but the black navigation bar is not visible (Disappears before it appears visibly).

// Creates the PopupMenu.
PopupMenu popup = new PopupMenu(getContext(), view)
{
    @Override
    public void show()
    {
        // Shows the menu.
        super.show();

        // Sets the UI flags to prevent weird changing of window.
        Handler temp = new Handler();
        temp.postDelayed(new Runnable()
        {
            @Override
            public void run()
            {
                getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
                    View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                    View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
                    View.SYSTEM_UI_FLAG_FULLSCREEN |
                    View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
            }
        }, 50);
    }
}
Gabrielson answered 2/10, 2019 at 14:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.