本文说的沉浸式状态栏不是真正意义上的沉浸式(状态栏会收缩隐藏起来),而是目前国内国产手机提到的沉浸式状态栏,即是状态栏的背景色跟界面顶部(可简单理解为标题栏)的颜色保持一致。
最近发现越来越多的应用开始实现沉浸式状态栏。从视觉角度上看是挺好的。
本文会提及几种实现方式。
方式一:纯色状态栏
先上图吧。
下面看代码:
public static void initStatusBarStyle(Activity activity, int color) {
if (Build.VERSION.SDK_INT >= 21) {
Window window = activity.getWindow();
//取消设置透明状态栏,使 ContentView 内容不再覆盖状态栏
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//需要设置这个 flag 才能调用 setStatusBarColor 来设置状态栏颜色
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
//设置状态栏颜色
window.setStatusBarColor(color);
}
}
这里代码量很少,就五六句代码。这种方式其中用到了window.setStatusBarColor(color);故而只能在API21以上系统使用。
同时还存在一种情况,当设置状态栏的颜色为白色的时候,当状态栏的文本颜色也为白色的时候,显示效果就成了这样,
这样就很无语了,没办法,想办法处理咯,最后找到两篇文章,讲了下处理办法,
http://www.jb51.net/article/77804.htm
http://www.zhihu.com/question/31994153
但是也只是提供了小米手机及魅族手机和Android6.0上的处理方法。
我这里测试用的是小米的手机,所以来看下对小米手机的处理方法:
public static boolean setMiuiStatusBarDarkMode(Activity activity, boolean darkmode) {
Class<? extends Window> clazz = activity.getWindow().getClass();
try {
int darkModeFlag = 0;
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(activity.getWindow(), darkmode ? darkModeFlag : 0, darkModeFlag);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
就是通过反射修改相应的系统窗口配置。
下面我们来看下通过以下方式来实现沉浸式状态栏。activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
以上方式是API19之后才有提供的。也就是说使用这种方式只有Android4.4.4及以上方式才能实现沉浸式状态栏。
直接上代码,
public static void initStatusBarStyle(Activity activity, int color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
activity.getWindow().setStatusBarColor(color);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
View statusBarView = contentView.getChildAt(0);
//避免重复添加statusBarView
if (statusBarView != null && statusBarView.getMeasuredHeight() == getStatusBarHeight(activity)) {
statusBarView.setBackgroundColor(color);
return;
}
statusBarView = new View(activity);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
getStatusBarHeight(activity));
statusBarView.setBackgroundColor(color);
contentView.addView(statusBarView, lp);
}
}
通过设置activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);后,我们的标题栏会变成半透明效果悬浮在屏幕顶部,而我们的应用界面会全屏显示,我们来看效果:
Android 5.1
Android4.4.4
通过图片我们发现存在两个问题,一个是我们的内容跟状态栏重叠了,其二是4.4.4系统的依旧是存在上文说的状态栏颜色(白色)跟文本颜色(白色)的问题。
这里我们来看第一个问题,解决方法是。在我们应用的内容区域(layout中最上面的view)增加android:fitsSystemWindows=”true”属性即可。
或者代码中设置setFitsSystemWindows(true);这个是给状态栏预留空间
我这里顶部是标题栏,就给标题栏设置。设置这个后系统会处理给标题栏增加相应的padding来使得内容区域看上去下移一个状态栏高度的距离。
效果如开文
下面贴下Android4.4.4中获取状态栏高度的代码
public static int getStatusBarHeight(Context context) {
int result = 0;
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
文章中提到的沉浸式存在一定的不足,我再看看怎么优化,有好的建议请留言告诉我。