你的Android应用应该主动适配沉浸式状态栏

什么是沉浸式状态栏?

沉浸式状态栏 准确来说应该是“透明栏”,英文名“Translucent Bars”,是Android 4.4 新定义的设计规范。 Google 在 Android 4.4 的 API 描述页面里提到了“Translucent system UI styling”,即半透明化的系统UI风格。 这个“半透明化”包括了状态栏和通知栏,当开发者让应用支持这个新特性的时候,状态栏和导航栏可以单独/同时变为渐变的半透明样式。

为什么应用要支持沉浸式状态栏特性?

  • 适配前

  • 适配后

简单来说,支持 “沉浸式状态栏” 之后,状态栏不再是只有Light,Dark两种;也不会说颜色上面显得很突兀,视觉上有颜色撕裂的问题,这样一来用户的注意力会更加集中在产品的内容上面,因此,你的应用主动的适配沉浸式状态栏,不管是在视觉上会给人以舒服,美感,在内容的突出和体验上也会有很大作用。

怎么实现沉浸式状态栏

主题Style配置

  • res->values->styles AppTheme
1
2
3
4
5
6
7
8
9
<style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
</style>
<style name="AppTheme" parent="BaseTheme">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:textCursorDrawable">@null</item>
</style>
  • res->values-v19->styles BaseTheme
1
2
3
<style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
</style>
  • res->values-v21->styles BaseTheme
1
2
3
4
<style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:windowTranslucentStatus">false</item>
</style>
  • res->values-v23->styles BaseTheme
1
2
3
4
<style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:windowTranslucentStatus">false</item>
</style>

在app基类Activity的setContentView之后调用setStatusBarColor

fullScreen: 指的是一般像应用入口闪屏界面,引导界面

lightStatusBar: 浅色状态栏,例如上面截图的白底黑字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//这里是基类的声明
protected boolean fullScreenMode(){
return false;
}
protected boolean lightStatusBar(){
return true;
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
StatusBarCompat.setStatusBarColor(this, fullScreenMode(), lightStatusBar(),getResources().getColor(R.color.colorPrimary));
}

如果你的Activity是fullScreen窗口, 那么应该调用translucentStatusBar方法, 否则调用setStatusBarColor

改变状态栏字体颜色

1、 小米系统,要求MIUI6以上

1
2
3
4
5
6
7
8
Class<? extends Window> clazz = window.getClass();
int darkModeFlag;
Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
darkModeFlag = field.getInt(layoutParams);
Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
extraFlagField.invoke(window, lightStatusBar ? darkModeFlag : 0, darkModeFlag);

2、 魅族系统,要求FlyMe4以上

1
2
3
4
5
6
7
8
9
10
11
12
WindowManager.LayoutParams lp = window.getAttributes();
Class<?> instance = Class.forName("android.view.WindowManager$LayoutParams");
int value = instance.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON").getInt(lp);
Field field = instance.getDeclaredField("meizuFlags");
field.setAccessible(true);
int origin = field.getInt(lp);
if (isLightStatusBar) {
field.set(lp, origin | value);
} else {
field.set(lp, (~value) & origin);
}

3、 API 23 以上的处理方法

1
2
3
4
5
6
int flag = window.getDecorView().getSystemUiVisibility();
flag |= (WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
window.setStatusBarColor(Color.WHITE);
window.getDecorView().setSystemUiVisibility(flag);

最后

附上相关链接

StatusBarCompat

Material Design

打赏作者