Android沉浸式状态栏实现方案

何为沉浸式状态栏?直接上图看效果:

like this

image

or like this

image

从效果上看,状态栏支持填充控件了,状态栏的文字位于填充的控件之上。沉浸式状态栏是Android4.4以后出来的新特性,所以你会发现在Android4.4之前的系统,状态栏基本都是漆黑一片。

目前我们使用的安卓手机,系统版本一般很少有低于Android4.4的了,然而在我们使用频率比较高的应用当中,使用了沉浸式状态栏的应用却是寥寥无几。(ps:我只发现QQ和一些系统预装应用使用了……)这到底是为神马啊。沉浸式状态栏的用户体验真的比顶部一坨乌漆麻黑好的呀。iOS的应用不都是沉浸式。。。原因在于Android系统只提供了状态栏沉浸的API,木有提供改变状态栏文字颜色的API。状态栏的文字一般都是白色的,如果你往状态栏填充的控件色调也是偏向白色,这就会导致状态栏的文字看不清了,反而降低了用户体验。所以一个应用该不该使用沉浸式状态栏,首先要考虑的是该应用的主色调是否和状态栏文字的颜色相协调。

Someone question:为啥有些手机的状态栏文字颜色不是白色的?你确定状态栏的文字颜色真的无法改变吗?

My answer:目前为止,真的无法通过Java代码来改变系统状态栏文字的颜色,以后谷歌提不提供API很难说。手机状态栏文字颜色变了的,显然是玩机发烧友把手机root了,修改了系统的配置文件。

好了,以上带大家了解了沉浸式,如果你的应用确定适合使用沉浸式,那么现在来说说实现方案。

方案一:直接改变状态栏的背景颜色,来实现视觉上的沉浸式。我们在Android Studio新建项目,运行到手机,然后发现状态栏是偏向于蓝色的,对不。怎么改颜色呢?在values文件夹找到styles.xml,修改AppTheme的colorPrimaryDark属性值。将颜色值改为和你标题栏一样的颜色值。

 <item name="colorPrimaryDark">@color/colorPrimaryDark</item>

这种方法只是改变了状态栏的背景颜色,并非真正地往状态栏里填充控件,所以只适用于所有界面的顶部都是标题栏的应用。

方案二:还是在AppTheme上做文章,添加item,属性名是android:windowBackground,它的值是drawable。亦即将所有界面的背景,设置为某张图片。

  <item name="android:windowBackground">@mipmap/bg_pic</item>

加上以后,状态栏会自动填充这张背景图到状态栏。这个方案只适用于整个应用的界面,都以某张图片为背景的情况。当然,这种应用真的真的很少见。。。

小结:以上两种方案都是通过修改主题样式而实现,简单粗暴到令人发指。

方案三:通过系统API来实现。这个就略微有点麻烦了。(也有使用SystemBarTint这个库的,其实都是一样的的的..麻烦…)在Activity的onCreate或者Fragment的OnCreateView方法里,加上:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}

然后在你的布局xml里,想让哪个View填充到状态栏,你就在那个View加上这句属性:

 android:fitsSystemWindows="true"

如果你的界面,顶部是图片,那么你填充该ImageView到状态栏即可。如果不是,一般来说都是填充与状态栏等高的View,并非是填充标题栏。在界面代码中,顶部加入一个View,背景色由你想填充的颜色决定:

<RelativeLayout
    android:id="@+id/bar_view"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:background="?attr/colorPrimary"
    android:fitsSystemWindows="true"/>

那状态栏的高度是多少呢?由于国产ROM千差万别,所以应该使用代码来获取状态栏的高度,动态设置成顶部View的高度。

 /**
     * 用于获取状态栏的高度。 使用Resource对象获取(推荐这种方式)
     *
     * @return 返回状态栏高度的像素值。
     */
    public int getStatusBarHeight() {
        int result = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen",
                "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

以上是获取状态栏高度的代码,然后findViewById初始化要填充的View,设置View的高度:


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    RelativeLayout barView = (RelativeLayout) findViewById(R.id.bar_view);
    barView.getLayoutParams().height = getStatusBarHeight();
}

到这里,沉浸式状态栏就已经实现了的。如果想每个界面都状态栏沉浸,那就把这些代码写到BaseActivity以及BaseFragment。至于布局里要填充的View,可以写到单独的一个xml里,用include标签引用。

最后,欢迎入坑。沉浸式状态栏是存在一点点坑的,这或许是很多应用不愿意使用沉浸式状态栏的原因之一吧。目前我发现的坑是,Activity无法adjustResize了。也就是输入法弹出时会把界面挡住,即使你设置了Activity的属性android:windowSoftInputMode=”adjustResize”。当然,解决方法是有的:监听输入法的显示或隐藏,动态改变根布局的高度,也就是手动实现adjustResize。这个代码我也写进了demo里,欢迎下载。

沉浸式状态栏demo地址

https://github.com/zengd0/FillStatusbarDemo

发布了32 篇原创文章 · 获赞 39 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/zengd0/article/details/52506737