1. 程式人生 > >安卓開發之設定狀態列的顏色

安卓開發之設定狀態列的顏色

要求:實現設定狀態列的顏色需要至少4.4.2(API 19以上)。在這個版本一下,沒有任何的API可以實現這樣的功能。具體實現方式如下:

一、Android 4.4.2 

新增了一個特性,就是可以設定系統狀態為半透明。設定方法有兩種:

1、通過style新增屬性:<item name="android:windowTranslucentStatus">true</item>

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新增了一個屬性來解決這樣的問題:如果我們設定的狀態列的顏色接近於白色的話,可以在主題中新增以下屬性:

<item name="android:windowLightStatusBar">true</tem>

當然也可以通過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。