Search code examples
androidlayoutfullscreen

SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION has no effect


I'm using this code inside a VideoView to try to hide the navigation bar on a Touchpad running Android (CyanogenMod) 4.1.

    setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | SYSTEM_UI_FLAG_FULLSCREEN
            | SYSTEM_UI_FLAG_HIDE_NAVIGATION);

Unfortunately it has no effect at all, and gives no error. I am at a loss what to look for (and I appreciate that "it doesn't work" isn't very helpful, but I am under the impression that that is the only line of code you need to use, and since there are no errors...)

I've tried various variations - getWindow().getDecorView().setSystemUiVi..., doing it in multiple places, on a timer, etc. That line of code is definitely reached but it simply doesn't do anything.


Solution

  • Oh how ridiculous. After reading the source code - which is often the only way to find things out in Android-land - I discovered the following undocumented fact:

    setSystemUiVisibility() only has effect when the view you call it from is visible!

    Even more: The view in which you call setSystemUiVisibility() must remain visible for the nav bar to remain hidden. Thanks for documenting that guys, really great.

    Here is the relevant code, in View.java.

    void performCollectViewAttributes(AttachInfo attachInfo, int visibility) {
        if ((visibility & VISIBILITY_MASK) == VISIBLE) {
            if ((mViewFlags & KEEP_SCREEN_ON) == KEEP_SCREEN_ON) {
                attachInfo.mKeepScreenOn = true;
            }
            attachInfo.mSystemUiVisibility |= mSystemUiVisibility;
            ListenerInfo li = mListenerInfo;
            if (li != null && li.mOnSystemUiVisibilityChangeListener != null) {
                attachInfo.mHasSystemUiListeners = true;
            }
        }
    }