可以看到,通过添加指定颜色的占位状态来达到沉浸效果的方案,在 4.4 系统上效果是正常的,但是在 6.0 上,在状态栏和 Actionbar 之间会有阴影,这个阴影是主题的效果。不知道大家还记不记得 Theme 主题里的几个设计颜色的属性:
colorPrimary 指定 ActionBar 的颜色,colorPrimaryDark 指定状态栏颜色,经过测试,在主题里将二者设为统一颜色,状态栏和 ActionBar 之间不会有黑边。自然,我们除了在 Theme 主题里设置,还可以直接在代码里通过上文提到过的代码修改 5.x 以上系统的状态栏颜色:
Window window = activity.getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); window.setStatusBarColor(Color.BLUE);但是因为 setStatusBarColor() 方法的参数无法传入 Drawble ,所以这种方式是无法实现渐变色状态栏的效果的。所以还是应该聚焦在怎么解决 ActionBar 阴影的问题,上面说了,既然这个阴影是 Theme 的效果,那就肯定有移除这种效果的方法,一种解决方法是更改主题为 ActionBar 不带阴影的主题样式:
<style parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item>@color/colorPrimary</item> <item>@color/colorPrimaryDark</item> <item>@color/colorAccent</item> <item>@null</item> //更改 ActionBar 风格样式 <item>@style/ActionBarStyleWithoutShadow</item> </style> //ActionBar 不带阴影的主题样式 <style parent="android:Theme.Holo.ActionBar"> <item>@color/blue</item> </style>还有第二种更简单的方式,那就是直接在代码里设置去除阴影:
/** * 去除 ActionBar 阴影 */ public StatusBarUtils clearActionBarShadow() { if (Build.VERSION.SDK_INT >= 21) { ActionBar supportActionBar = ((AppCompatActivity) mActivity).getSupportActionBar(); if (supportActionBar != null) { supportActionBar.setElevation(0); } } return this; }并且因为内容是位于 ActionBar 之下的,我们还必须给内容视图是指一个 paddingTop,高度为状态栏高度+ActionBar 高度,才可以使内容正常显示。我们给 ActionBar 设置一个渐变色试试看:
//drawble 文件夹内新建 shape 渐变色 <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:angle="0" android:centerX="0.7" android:endColor="@color/shape2" android:startColor="@color/shape1" android:centerColor="@color/shape3" android:type="linear" /> </shape> //ActionBar 设置渐变背景色 getSupportActionBar().setBackgroundDrawable(getResources().getDrawable(R.drawable.shape)); //占位状态栏 设置渐变背景色 View statusBarView = new View(activity); ... //增加占位状态栏方法同上,只是在设置 statusBarView 背景上有 color 和 drawble 之分 statusBarView.setBackground(drawable); if (isActionBar()) { //要增加内容视图的 paddingTop,否则内容被 ActionBar 遮盖 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { ViewGroup rootView = (ViewGroup) mActivity.getWindow().getDecorView().findViewById(android.R.id.content); rootView.setPadding(0, getStatusBarHeight(mActivity) + getActionBarHeight(mActivity), 0, 0); } }至此,尝试适配了几种比较常见的使用场景的沉浸式状态栏,效果也都还比较符合预期。真正去处理这个问题时会发现其实问题也没有想象中的那么复杂。最后附上 Github 源码。
Stay hungry. Stay foolish.
下篇博客再见。