沉浸式状态栏,不用我说,大家都知道。就是让你的应用跟状态栏融为一体,视觉上体验更加完美。
Android的沉浸式状态栏实现本来是挺简单的一件事情,但是大家有没有一种感觉,太乱了!本来还有一点思路的,看完网上一大堆的文章以后,更加的懵逼,感觉就是真TM的复杂。今天我就做一个最简单的总结,看完之后大家就知道怎么做了,不用那么复杂。
沉浸式状态栏主要分三种版本情况(4.4以下版本不做考虑,保持原状态栏):
一、Android 4.4:
4.4版本提供了一个透明状态栏(其实也不是全透明的,translucent是半透明的意思),不能设置状态栏文字反色,实现代码如下:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
效果就是这样子的(先不要管状态栏遮挡标题栏问题,等下再讲 fitsSystemWindows 的问题):
二、Android 5.0:
5.0版本提供了API可以自定义状态栏的颜色,相对于4.4版本,5.0版本的沉浸式状态栏实现简单多了,自己设置一个颜色就完了。此版本依然不能设置状态栏文字反色,即使有部分厂商开放了接口,但不是通用接口。实现代码如下:
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(ContextCompat.getColor(this, R.color.blue));
}
实现的效果如下:
如果你的标题栏的颜色是白色的,那效果就会变成这样子(状态的文字看不见了):
三、Android 6.0:
6.0版本才算是安卓真正意义上实现了沉浸式状态栏,因为它不但继承了5.0版本可以设置状态栏颜色,还可以设置状态栏文字反色。所以我的建议是,如果你的app是白色系,对6.0以上的手机才做沉浸式状态栏,6.0以下的版本保持原状态栏不变。6.0版本的实现代码如下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(ContextCompat.getColor(this, R.color.white_color));
//这是状态栏文字反色
setDarkStatusIcon(true);
}
/**
* 设置状态栏反色
*/
protected void setDarkStatusIcon(boolean isDark) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
View decorView = getWindow().getDecorView();
if (decorView != null) {
int vis = decorView.getSystemUiVisibility();
if (isDark) {
vis |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
} else {
vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
}
decorView.setSystemUiVisibility(vis);
}
}
}
效果是这样的:
OK,讲完Android不同版本的沉浸式状态栏的实现,我们来讲一下状态栏遮挡布局的问题,就是大家看到的4.4版本上实现透明状态栏的那张图。透明状态栏会使你的布局延伸至状态栏,所以就会有遮挡的问题。谷歌也发现了这个问题,所以提供了一个fitsSystemWindows的方案。
fitsSystemWindows=“true”是让你的View自动留出跟系统UI(状态栏、导航栏)一样高度的padding,以防止你的布局被系统UI遮挡。在根布局的xml文件加一个fitsSystemWindows的属性,就可以在透明状态栏下防止布局被遮挡
在4.4版本上加完之后是这样子的:
这样就解决了布局被遮挡的问题,但是很丑对不对?所以在4.4版本做沉浸式状态栏,你需要在contentView的前面插入一个view,这个view的高度跟状态栏的高度一样,颜色你可以自己定。怎么插入一个跟状态栏一样高度的view,我就不贴代码了,网上有很多(注意:如果是插入一个view的话,fitsSystemWindows就不需要设置了)
5.0以上的版本是直接绘制状态栏的颜色,所以不需要插入一个view,也不用设置fitsSystemWindows。只有设置状态栏透明的情况,才需要设置fitsSystemWindows。OK,来看一下下面一种情况:
如果是要这种效果的状态栏怎么办?显然你不能通过绘制状态栏的颜色来解决,因为布局的顶部是图片,不是纯色的。也许你会说,把状态栏设置成透明的就可以了,所以加入一行代码:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
结果是这样的:
可以看到半透明状态栏,并不符合沉浸式状态栏要求,其实 TRANSLUCENT 是半透明的意思,并不是全透明。那可能有同学说,直接把状态栏绘制成透明的颜色行不行?像这样:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(ContextCompat.getColor(this, android.R.color.transparent));
}
答案是:不行。因为你的布局并没有渗透到状态栏,结果会是这样的
所以综合起来就是,你要让你的布局延伸至状态栏,然后把状态栏设置成透明,就可以了,正确的姿势如下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
View decorView=getWindow().getDecorView();
int option=View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
decorView.setSystemUiVisibility(option);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
再运行一次,最终的效果就是这样子:
到这里,沉浸式状态栏就已经全部实现了,没有什么更特殊的情况了,无非就是要么自己为状态栏设置一个颜色,要么就是把状态栏设置成透明,只是版本实现上有差异,至于要不要设置fitsSystemWindows,看你自己的情况,你知道它是什么意思就行了,网上的文章越说越乱,搞得好像很复杂的样子,其实不难的。