使用 NoActionBar 主题,并使用下面的
<style name="TranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
Android 提供了三个用于将应用设为全屏模式选项:向后倾斜模式、沉浸模式和粘性沉浸模式。在所有三种方法中,系统栏都是隐藏的,您的 Activity 会持续收到所有轻触事件。 它们之间的区别在于用户让系统栏重新显示出来的方式。
向后倾斜模式适用于用户不会与屏幕进行大量互动的全屏体验,例如在观看视频时。
当用户希望调出系统栏时,只需点按屏幕上的任意位置即可。
如需启用向后倾斜模式,请调用 setSystemUiVisibility() 并传递 SYSTEM_UI_FLAG_FULLSCREEN 和 SYSTEM_UI_FLAG_HIDE_NAVIGATION。
SYSTEM UI FLAG 解析:
View.SYSTEM_UI_FLAG_FULLSCREEN
隐藏状态栏,点击屏幕区域不会出现,需要从状态栏位置下拉才会出现。
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
隐藏导航栏,点击屏幕任意区域,导航栏将重新出现,并且不会自动消失。
沉浸模式适用于用户将与屏幕进行大量互动的应用。示例包括游戏、查看图库中的图片或者阅读分页内容,如图书或演示文稿中的幻灯片。
当用户需要调出系统栏时,他们可从隐藏系统栏的任一边滑动。要求使用这种这种意图更强的手势是为了确保用户与您应用的互动不会因意外轻触和滑动而中断。
要启用沉浸模式,请调用 setSystemUiVisibility() 并将 SYSTEM_UI_FLAG_IMMERSIVE 标志与 SYSTEM_UI_FLAG_FULLSCREEN 和 SYSTEM_UI_FLAG_HIDE_NAVIGATION 一起传递。
SYSTEM UI FLAG 解析:
View.SYSTEM_UI_FLAG_IMMERSIVE
使状态栏和导航栏真正的进入沉浸模式,即全屏模式,如果没有设置这个标志,设置 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 时,我们点击屏幕的任意位置,导航栏就会恢复为正常模式。所以,View.SYSTEM_UI_FLAG_IMMERSIVE 都是配合View.SYSTEM_UI_FLAG_FULLSCREEN 和 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 一起使用的。
在粘性沉浸模式下,如果用户从隐藏了系统栏的边缘滑动,系统栏会显示出来,但它们是半透明的,并且轻触手势会传递给应用,因此应用也会响应该手势。
例如,在使用这种方法的绘图应用中,如果用户想绘制从屏幕最边缘开始的线条,则从这个边缘滑动会显示系统栏,同时还会开始绘制从最边缘开始的线条。无互动几秒钟后,或者用户在系统栏之外的任何位置轻触或做手势时,系统栏会自动消失。
要启用粘性沉浸模式,请调用 setSystemUiVisibility() 并将 SYSTEM_UI_FLAG_IMMERSIVE_STICKY 标志与 SYSTEM_UI_FLAG_FULLSCREEN 和 SYSTEM_UI_FLAG_HIDE_NAVIGATION 一起传递。
SYSTEM UI FLAG 解析:
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
它的效果跟 View.SYSTEM_UI_FLAG_IMMERSIVE 一样。但是,它在全屏模式下,用户上下拉状态栏或者导航栏时,这些系统栏只是以半透明的状态显示出来,并且在一定时间后会自动消失。
从 SDK 30 开始,系统不再推荐使用 setSystemUiVisibility 控制状态栏和导航栏,而是推荐使用 WindowInsetsController 实现相关的功能
在 onCreate 中 setContentView() 方法调用后,或者在 onResume 中加入下面代码实现全屏
getWindow().setDecorFitsSystemWindows(false);//1
WindowInsetsController windowInsetsController = getWindow().getInsetsController();//2
windowInsetsController.hide(WindowInsets.Type.systemBars());//3
windowInsetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);//4
解析:
注释 1 是让 DecorView 不接受 fitsSystemWindows 分发,所以 Statusbar 不会造成的 DecorView 对 ContentView 的padding,但是 ContentView 可能会接受 fitsSystemWindows 方法,产生 padding,参考《fitsSystemWindows 分发》
注释 2 是获取当前 Window 的 WindowInsetsController ,其实就是 DecorView 的 WindowInsetsController ,注意该方法要在 setContentView() 方法后调用,因为 DecorView 是在 setContentView() 方法执行时初始化的
//二者 hashCode 完全相同
Log.d(TAG, "onCreate: " + getWindow().getInsetsController().hashCode());
Log.d(TAG, "onCreate: " + getWindow().getDecorView().getWindowInsetsController().hashCode());
注释 3 用于隐藏 systembar(即 statusbar、navigationbar、
captionBar),除了 systembar,还可以隐藏
WindowInsets.Type.statusBars();
WindowInsets.Type.navigationBars();
WindowInsets.Type.captionBar();
WindowInsets.Type.systemGestures();
WindowInsets.Type.systemBars();
//....
注释 4 用于设置 systembar 行为,BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE,意味着当用户从上往下滑动时,系统将短暂出现一个半透明的 systembar
https://jishuin.proginn.com/p/763bfbd6deb3
https://developer.android.google.cn/training/system-ui/immersive#immersive-consolidated-behavior
https://blog.csdn.net/QQxiaoqiang1573/article/details/79867127