百度百科对沉浸式的定义是给用户提供一种完全沉浸的体验,使用户有一种置身于虚拟世界之中的感觉,比如现在大热的VR就是主打的沉浸式体验,对应到操作系统,这种沉浸式体验我们就经常看到了,游戏类或者影视类的应用都希望让用户完全沉浸在其中,享受他们提供的娱乐内容,也就是说让屏幕100%的空间用来展示内容。
先来两张截图
一张是游戏
一张是播放视频的时候
这时候你看不到导航栏和状态栏,整个屏幕都被内容填充了,这才是真正的沉浸式
当你触碰屏幕顶端等操作时又会把导航栏状态栏带出来,,这才是真正的沉浸式
今天我们一步一步来看看这东西如何来实现它,一般来说,这种沉浸式只在4.4及其以上版本才会有,而实现方式有通过代码控制和通过xml文件这两种,从灵活性来说当然是前者
我们看第一种情况,像美团饿了么这些应用就是采用把布局浸入状态栏来实现的
分两种情况,
1:状态栏透明,导航栏不透明(默认黑色),主体内容(不)占用系统导航栏的空间
/**透明状态栏
* SYSTEM_UI_FLAG_LAYOUT_FULLSCREENSYSTEM_UI_FLAG_LAYOUT_STABLE,
* 注意两个Flag必须要结合在一起使用,表示会让应用的主体内容占用系统状态栏的空间,
* 最后再调用Window的setStatusBarColor()方法将状态栏设置成透明色就可以了。
* 导航栏则不作处理默认黑色
*/
if (Build.VERSION.SDK_INT >= 21) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
2:状态栏透明,导航栏不透明颜色自定义,主体内容(不)占用系统导航栏的空间
if (Build.VERSION.SDK_INT >= 21) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
//设置状态栏和导航栏的颜色,下边这俩方法5.0及其以上可用
getWindow().setNavigationBarColor(Color.TRANSPARENT);//透明
getWindow().setStatusBarColor(R.corlor.xxx);//自定义
}
3.透明状态栏,透明导航栏,应用的主体内容占用系统导航栏的空间
/**
* 透明状态栏,透明导航栏
* 使用了SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION,表示会让应用的主体内容占用
* 系统导航栏的空间,
* 然后又调用了setNavigationBarColor()方法将导航栏设置成透明色
*/
if (Build.VERSION.SDK_INT >= 21) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
//设置状态栏和导航栏的颜色
getWindow().setNavigationBarColor(Color.TRANSPARENT);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
4:虽然这个沉浸式是一种误叫的称呼,但沉浸模式的确是存在的,这种效果只是在游戏或者视频软件这类特殊的应用上边才会用到,如果确实要使用沉浸式,只需要重写Activity的onWindowFocusChanged()方法,加入如下逻辑即可
/**
* 像海岛骑兵和爱奇艺那样的沉浸式 真正的沉浸式
* 界面默认情况下是全屏的,状态栏和导航栏都不会显示。而当我们需要用到状态栏或导航栏时,
* 只需要在屏幕顶部向下拉,或者在屏幕右侧向左拉,状态栏和导航栏就会显示出来,
* 此时界面上任何元素的显示或大小都不会受影响。过一段时间后如果没有任何操作,
* 状态栏和导航栏又会自动隐藏起来,重新回到全屏状态。
*/
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && Build.VERSION.SDK_INT >= 19) {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
5:兼容4.4的透明导航栏状态栏
//当系统版本为4.4或者4.4以上时可以使用沉浸式状态栏,,
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//透明状态栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//透明导航栏 如果只是想要更改状态栏 这句可以注销
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
6:上边我们看到设置状态栏和导航栏颜色的方法 原生的必须要在5.0及其以上才能用 这就很蛋疼了,为了解决主要是4.4的兼容问题,我们引入一个第三方的类
SystemBarTintManager,这个类可以去GitHub去找到,基于此,我们可以实现全屏,标题栏一体化
//先设置状态栏和导航栏为透明,然后使用SystemBarTintManager进行颜色设置
//当系统版本为4.4或者4.4以上时可以使用沉浸式状态栏,,
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//透明状态栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//透明导航栏 如果只是想要更改状态栏 这句可以注销
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
// 创建状态栏导航栏的管理实例
SystemBarTintManager tintManager = new SystemBarTintManager(this);
// 激活状态栏设置
tintManager.setStatusBarTintEnabled(true);
// 激活导航栏设置,如果Navigation不想改变颜色,此处设置为false即可
tintManager.setNavigationBarTintEnabled(true);
// 设置一个颜色给系统栏,这个方法会把状态栏和导航栏设置为一样的颜色,这就不好了
//当然,如果你想设置一样的颜色,那么你随便啊
//tintManager.setTintColor(Color.parseColor("#FFFF6666"));
//给状态栏设置颜色
//Apply the specified drawable or color resource to the system status bar.
tintManager.setStatusBarTintResource(R.color.mask_tags_1);
//Apply the specified drawable or color resource to the system navigation bar.
//给导航栏设置资源
tintManager.setNavigationBarTintResource(R.color.mask_tags_2);
}