安卓开发之设置状态栏的颜色

要求:实现设置状态栏的颜色需要至少4.4.2(API 19以上)。在这个版本一下,没有任何的API可以实现这样的功能。具体实现方式如下:


一、Android 4.4.2 

新增了一个特性,就是可以设置系统状态为半透明。设置方法有两种:

1、通过style添加属性:true

2、通过JAVA代码设置

Window window=activity.getWindow();

window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);


系统设置成半透明之后,我们就可以通过网Window窗口的decoView添加一个View,让它大小与系统状态栏一样,然后设置这个View的背景,这样就实现了改变状态栏的目的了。代码如下:

ViewGroup decorViewGroup =(ViewGroup)window.getDecorView();

View statusBarView=new View(window.getContext());

int statusBarHeight=getStatusBarHeight(window.getContext());

FrameLayout.LayoutParams params=new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,statusBarHeight);

params.gravity=Gravity.TOP;

statusBarView.setLayoutParams(params);

statusBarView.setBackgroundColor(color);

decorViewGroup.addView(statusBarView);

其中获取状态栏的高度的方法代码为:

private static int getStatusBarHeight(Context context){

int statusBarHeight=0;

Resource res=context.getResource();

int resourceId=res.getIdentifier("status_bar_height","dimen","android");

if(resourceId>0){

statusBarHeight=res.getDimensionPixelSize(resourceId);

}

return statusBarHeight;

}

然后我们在Acticity的Oncreate方法中使用以上代码就行了。

但是在使用的时候,会发现Activity的布局内容顶到了状态栏上去,被状态栏及ActionBar所覆盖。解决方法很简单,只要在布局文件的根元素设置一下属性:android:fitsSystemWindows="true"

它的意思是使这个layout内嵌,也就是会为状态栏等留出空间,于是我们的布局就回复正常了。

但是问题来了,加入有十几个Activity,每一个都要修改它的布局文件,那多麻烦啊。解决办法是在Application主题中配置这个属性。但是衍生出来的一个问题就是Toast显示不正常了,文字会超出黑色背景之外。解决办法是,在setContentView()之后,加入一下代码:

ViewGroup mContentView =(ViewGroup)window.findViewById(Window.ID_ANDROID_CONTENT);

View mChildView=mContentView.getChildAt(0);

if(mChildView!=NULL){

//注意不是设置ContentView的FitsSystemWindows,而是设置ContentView的第一个子View,预留出系统View的空间。

mChildView.setFitsSystemWindows(fitSystemWindows);

}

二、Android 5.0.1

在这个版本中又增加了一些新的特性,包括一个重要的方法:window.setStatusColor(Color);

直接设置状态栏的颜色,但是想要生效,必须设置一个FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS属性,并且确保FLAG_TANSLUCENT_STATUS不被设置。

Window window=activity.getWindow();

//取消设置透明状态栏,使ContentView内容不再覆盖状态栏

window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

//需要设置这个flag才能调用setStatusBarClor来设置状态栏的颜色

window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUND);

//设置状态栏的颜色

window.setStatusBarColor(color);

三、Android  6.0

本版本设置状态栏的颜色与上面的一致,代码跟上面一样

//取消设置透明状态栏,使ContentView内容不再覆盖状态栏

window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

//需要设置这个flag才能调用setStatusBarClor来设置状态栏的颜色

window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUND);

//设置状态栏的颜色

window.setStatusBarColor(color);

但是在这里,如果我的状态栏被设置成白色的话,上面同样白色的系统状态就看不到了。不过6.0的API新增了一个属性来解决这样的问题:如果我们设置的状态栏的颜色接近于白色的话,可以在主题中添加以下属性:

true

当然也可以通过JAVA代码来实现:

View decor =window.getDecorView();

int ui=decor.getSystemUiVisibility();

if(lightStatusBar){

ui |=View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;

}else {

ui &=View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;

}

decor.setSystemUiVisibility(ui);

四、快速实现

在项目的build.gradle中声明以下依赖

compile 'com.githang:status-bar-compat:0.3'

在Activity中添加下面的代码,在setContentView()被调用之后

StatusBarCompat.setStatusBarColor(this,color,lightStatusBar);

不用考虑版本,不用考虑fitsSystemWindows问题,不用考虑状态栏被设置成白色后看不到系统状态的问题,并且兼容MIUI及Flyme。




你可能感兴趣的:(学习笔记)