我一直在与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
是否有效?我认为文档(惊喜)在这里有点缺乏。有谁知道真正发生了什么?
答案 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
);
}
}
}
答案 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);
}
}