setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)不起作用

时间:2013-01-06 01:06:07

标签: android android-layout android-fullscreen

我一直在与setSystemUiVisibility()斗争,试图隐藏一段时间的软导航按钮(对于视频播放器)。它似乎不像宣传的那样工作。这是我的代码,位于可见的FrameLayout内。

void setNavVisibility(boolean visible)
{
    int newVis = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
    if (!visible)
    {
        newVis |= SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_HIDE_NAVIGATION;
    }
    setSystemUiVisibility(newVis);
}

从SDK示例略微修改:

    void setNavVisibility(boolean visible) {
        int newVis = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | SYSTEM_UI_FLAG_LAYOUT_STABLE;
        if (!visible) {
            newVis |= SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_FULLSCREEN
                    | SYSTEM_UI_FLAG_HIDE_NAVIGATION;
        }

调用时都不做任何事情。当我从另一个View调用它们时,我取得了一些成功,但文档中没有提到您调用的View是否有效?我认为文档(惊喜)在这里有点缺乏。有谁知道真正发生了什么?

6 个答案:

答案 0 :(得分:25)

嗯,显然我duplicated my own question!但是无论如何我找到了答案:在阅读源代码 - 这通常是在Android-land中找到问题的唯一方法之后 - 我发现了以下未记录的事实:

setSystemUiVisibility()仅在您调用它的视图可见时生效!

更多:您调用setSystemUiVisibility()的视图必须保持可见,导航栏才能保持隐藏状态。感谢您记录这些人,非常棒。

以下是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;
        }
    }
}

答案 1 :(得分:5)

我使用setOnSystemUiVisibilityChangeListener()使这个全屏模式对我有用,包括隐藏导航栏。

@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();
}

似乎android只在侦听器内部触发setSystemUiVisibility()。

答案 2 :(得分:3)

我在下面实现了这个,但是我在底部有一个空白的空白(见截图)

@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
            );
        }
    }
}

enter image description here

答案 3 :(得分:1)

您确定没有用户互动吗?即模仿触摸,使控件立即重新出现?

来自docs

  

SYSTEM_UI_FLAG_HIDE_NAVIGATION:存在一个限制:因为导航控件非常重要,所以用户交互最少会导致它们立即重新出现。发生这种情况时,此标志和SYSTEM_UI_FLAG_FULLSCREEN都将自动清除,以便两个元素同时重新出现。

另一方面,我注意到在某些情况下,即使使用JB中的股票视频播放器,视图也没有调整大小。我认为这是(或者是)一个错误。

答案 4 :(得分:0)

我发现,如果用户与设备进行交互,则导航栏将返回。 立即在OnSystemUiVisibilityChangeListener处理程序方法中设置标志将不起作用。如果您在一秒钟的延迟后更改了它们,那将会起作用。

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();
}

答案 5 :(得分:0)

//do it by the following method hide it the status bar in sdk < 19 and for 
// greater u can do by providing the by the following i am doing here for both



      public void FullScreencall() {
    if (Build.VERSION.SDK_INT < 19) {
        getWindow().getDecorView().setSystemUiVisibility(8);
     }
    else {
        getWindow().getDecorView().setSystemUiVisibility
     (InputDeviceCompat.SOURCE_TOUCHSCREEN);
     }
   }