需求
在一个底部有虚拟导航栏NavigationBar
的手机上,需要全屏显示,完全隐藏顶部的StatusBar
和底部的NavigationBar
,在任何时候都不需要其显示出来.
异常现象
当给目标Activity
设置好全屏代码
Window window = getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE
| View.SYSTEM_UI_FLAG_FULLSCREEN;
window.getDecorView().setSystemUiVisibility(uiOptions);
后,可以正常显示全屏, 也不会出什么问题.
但是,如果弹出了一个DialogFragment
的时候,底部就会弹出虚拟导航栏,且当DialogFragment
消失的时候也不会跟着消失, 就很麻烦.
解决办法
查阅了stackoverflow
的某些答案后, 找到了一个比较好的办法.
- 首先,将设置全屏方法提取到一个工具类中
Util.java
public static void fullScreen(Window window) {
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE
| View.SYSTEM_UI_FLAG_FULLSCREEN;
window.getDecorView().setSystemUiVisibility(uiOptions);
}
- 在
DialogFragment
的onViewCreated
方法里加入一个FLAG
参数
getDialog().getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
这样弹出来的DialogFragment
就不会获取到系统焦点,也就不会显示底部导航拉了.
但是这会引起一个问题, 就是点击DialogFragment
的周围,他不会自动dismiss
消失,所有有了第三步.
- 在
DialogFragment
显示后,去掉这个FLAG_NOT_FOCUSABLE
.去掉这个标志后,DialogFragment
重新获取到焦点,所以点击周围可以关闭掉他. 同时,底部导航栏这个时候又会显示出来, 所以要在DialogFragment
显示的onShow()
的时候,再次调用设置全屏的方法,设置为全屏.
getDialog().setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
getDialog().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
//清除FLAG后,部分手机会再次显示底部导航栏,所以需要再次设置为全屏
Util.fullScreen(window);
}
});
至此, DialogFragment
可以正常显示了.
总结
DialogFragment
部分的代码如下
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (getDialog() != null) {
Window window = getDialog().getWindow();
if (window != null) {
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
getDialog().setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
Util.fullScreen(window);
}
});
}
}
}