setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) does not work

后端 未结 5 1983
隐瞒了意图╮
隐瞒了意图╮ 2020-12-03 03:46

I\'ve been battling with setSystemUiVisibility() to try to hide the soft navigation buttons for a while (for a video player). It does not seem to work as advertised. Here is

相关标签:
5条回答
  • 2020-12-03 04:19

    I implemented this as below however I get a blank gap at the bottom (see screenshot)

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                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_LOW_PROFILE
                                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                                | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                );
            }
        }
    }
    

    0 讨论(0)
  • 2020-12-03 04:22

    Are you sure no user interaction is going on? i.e. emulating a touch which causes the controls to instantly reappear?

    From the docs:

    SYSTEM_UI_FLAG_HIDE_NAVIGATION: There is a limitation: because navigation controls are so important, the least user interaction will cause them to reappear immediately. When this happens, both this flag and SYSTEM_UI_FLAG_FULLSCREEN will be cleared automatically, so that both elements reappear at the same time.

    On a side note, I've noticed issues with the view not resizing under some circumstances even with the stock video player in JB. I think it's (or was) a bug.

    0 讨论(0)
  • 2020-12-03 04:29

    I found that if the user interacted with the device then the navigation bar would return. Immediately setting the flags in the OnSystemUiVisibilityChangeListener handler method would not work. It would work if you changed them after a one second delay.

    protected static final int requiredDecorViewFlags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LOW_PROFILE
            | View.SYSTEM_UI_FLAG_FULLSCREEN
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
    
    
    protected void listenToUiVisibilityChange() {
        Window window = getWindow();
        if(window == null) {
            return;
        }
        final View view = window.getDecorView();
        if(view == null) {
            return;
        }
        view.setOnSystemUiVisibilityChangeListener(
            new View.OnSystemUiVisibilityChangeListener() {
                @Override
                public void onSystemUiVisibilityChange(int visibility) {
                    Handler handler = new Handler(
                        getMainLooper()
                    );
                    handler.postDelayed(
                        new Runnable() {
                            @Override
                            public void run() {
                                Window activityWindow = getWindow();
                                if(activityWindow == null) {
                                    return;
                                }
                                View decorView = activityWindow.getDecorView();
                                if(decorView == null) {
                                    return;
                                }
                                decorView.setSystemUiVisibility(requiredDecorViewFlags);
                           }
                       },
                       1000
                   );
               }
           }
        );
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        listenToUiVisibilityChange();
    }
    
    0 讨论(0)
  • 2020-12-03 04:37

    I use setOnSystemUiVisibilityChangeListener() to make this full screen mode work for me including hiding the navigation bar.

    @Override
    protected void onResume() {
        if (Build.VERSION.SDK_INT >= 16) {
            getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(
                    new OnSystemUiVisibilityChangeListener() {
                        @Override
                        public void onSystemUiVisibilityChange(int visibility) {
                            if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
                                getActionBar().show();
                            } else {
                                int mUIFlag = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                                        | View.SYSTEM_UI_FLAG_LOW_PROFILE
                                        | View.SYSTEM_UI_FLAG_FULLSCREEN
                                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
                                getWindow().getDecorView()
                                        .setSystemUiVisibility(mUIFlag);
                                getActionBar().hide();
                            }
                        }
                    });
        }
    
        super.onResume();
    }
    

    it seems that android only trigger the setSystemUiVisibility() when inside the listener.

    0 讨论(0)
  • 2020-12-03 04:38

    Hmm apparently I duplicated my own question! But anyway I found the answer: 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;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题