Android史上最简单的沉浸式状态栏实现,不要再乱了

沉浸式状态栏,不用我说,大家都知道。就是让你的应用跟状态栏融为一体,视觉上体验更加完美。

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的属性,就可以在透明状态栏下防止布局被遮挡

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

在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,看你自己的情况,你知道它是什么意思就行了,网上的文章越说越乱,搞得好像很复杂的样子,其实不难的。

发布了27 篇原创文章 · 获赞 24 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/shving/article/details/95805424
今日推荐