概述
Android 从4.4(API 19)开始让系统最上方的状态栏(Status Bar)和最下方的导航栏(Navigation Bar)可以被透明化,使得APP中的设计可以过渡更加平滑,不像之前那样的割裂感,让整个APP更加一致。
在进行透明化处理之前,我们可以看到如下默认显示:
如上,整个系统的status bar 显示的是全黑色,而APP内容显示区域为红色。现在我们对status bar 进行透明化处理,这里有两种方法来进行设置,一种是通过java代码进行设置,一种是通过styles来设置。我们来一一介绍。
开始状态栏的设置
通过java代码中进行设置:
// 当系统的版本号大于等于KitKat版本
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = getWindow();
// Translucent status bar
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// Translucent navigation bar
window.setFlags(
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
上面代码,判断系统运行的版本号,然后一行设置status bar和一行设置Navigation Bar。
注意:在对应的布局中根节点中,还需要添加属性:android:fitsSystemWindows=”true”,这样可以避免系统状态栏和我们的UI重叠。
通过设置主题风格Styles进行设置:
我们首先在项目中增加一个values-v19的资源目录,该目录中主要是针对API19设计适配的资源。
然后,在values-v19/style.xml中设置如下:
<resources>
<style name="AppTheme" parent="AppBaseTheme">
<!-- 设置系统Status Bar颜色透明 -->
<item name="android:windowTranslucentStatus">true</item>
<!-- 设置系统Navigation Bar颜色透明 -->
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:fitsSystemWindows">true</item>
</style>
</resources>
然后在AndroidManifest.xml中对指定Activity的theme进行设置。
上面的两种方式都可以实现相同的效果,如图:
自定义状态栏中的颜色
通过上面的两种方式,我们知道如何设置状态栏中透明化。这时我们如果想要自行的定制状态栏的颜色显示,应该怎样处理呢?我们当然可以通过设置根布局中的背景色,来设置状态栏中的颜色。如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_green_light"
android:orientation="vertical" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
上面的设置可以达到修改状态栏中颜色的目的,但是这样的方法有一个弊端,可能会造成界面过渡重绘。因为我如果只要求状态栏是该颜色,但是别的view是另外的颜色,我们就需要在别的子布局中重新设置其他颜色了,这样的就会导致界面过渡重绘了。我们就需要考虑其他的方法了。
那么有什么方法呢可以解决这个问题呢?
还记得在上面设置属性:android:fitsSystemWindows=”true” ,如果没有设置这个属性,会导致我们的UI与status bar 区域重叠吗?
这说明当设置属性:android:windowTranslucentStatus = true 时,我们可以进入到状态栏的区域了。既然如此,我们可以在根布局content中创建一个与状态栏等高的View,自定义其背景色就解决了。
代码如下:
package com.yuminfeng.myviewpager;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
/**
* 4.4 状态栏兼容,定义状态栏颜色
*
* @author Administrator
*
*/
public class StatusBarCompat {
private static final int INVALID_VAL = -1;
private static final int COLOR_DEFAULT = Color.parseColor("#20000000");
public static void compat(Activity activity){
compat(activity, COLOR_DEFAULT);
}
/**
* 给status bar 设置自定义颜色
* @param activity
* @param statusColor
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static void compat(Activity activity,int statusColor){
//当系统SDK为5.x时,直接使用API21提供的方法setStatusBarColor设置status bar的颜色
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
if(statusColor != INVALID_VAL){
activity.getWindow().setStatusBarColor(statusColor);
}
return;
}
//当系统SDK为4.4时,自定义一个与状态栏等高的View
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP){
int color = COLOR_DEFAULT;
ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
if(statusColor != INVALID_VAL){
color = statusColor;
}
View stautsBarView = new View(activity);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT,getStatusBarHeight(activity));
stautsBarView.setBackgroundColor(color);
contentView.addView(stautsBarView, lp);
}
}
private 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;
}
}
引入上面的类之后,只需在Actvity中调用即可:
StatusBarCompat.compat(this,Color.RED);
可以自己设置希望的颜色值。
上面就解决了4.4中状态栏的颜色设置问题。
对于android 5.0 中,系统直接提供了设置状态栏颜色的接口setStatusBarColor,但是这个方法与属性android:windowTranslucentStatus不能同时存在。所以,需要编写对应API的values目录。如values-v21,新建一个styles.xml文件
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
</style>
</resources>
当运行系统为5.0时,便使用该主题样式,避免了android:windowTranslucentStatus属性。当系统为5.1时,同样使用上面类似5.0中一样即可。
效果图如下:
参考博客:http://blog.youkuaiyun.com/lmj623565791/article/details/48649563