12

我一直在与 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你打电话的地方有什么影响?我认为这里的文档(出乎意料)有些缺乏。有谁知道到底发生了什么?

4

6 回答 6

31

嗯,显然我重复了我自己的问题!但无论如何我找到了答案:在阅读了源代码之后——这通常是在 Android 领域找到问题的唯一方法——我发现了以下未记录的事实:

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;
        }
    }
}
于 2013-01-06T16:16:17.747 回答
7

我使用 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() 。

于 2014-10-21T07:30:59.180 回答
5

我实现了这个如下但是我在底部得到一个空白(见截图)

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

在此处输入图像描述

于 2017-02-07T10:37:17.597 回答
1

您确定没有进行用户交互吗?即模拟导致控件立即重新出现的触摸?

文档

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

附带说明一下,即使使用 JB 中的股票视频播放器,我也注意到在某些情况下视图无法调整大小的问题。我认为这是(或曾经是)一个错误。

于 2013-01-06T01:11:36.900 回答
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();
}
于 2020-05-18T02:06:49.883 回答
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);
     }
   }
于 2021-06-17T12:20:32.133 回答