setColor()
設置狀態欄顏色
從設置狀態欄顏色方法開始看.
public class StatusBarUtil {
/**
* 設置狀態欄顏色
*
* @param activity 需要設置的 activity
* @param color 狀態欄顏色值
*/
public static void setColor(Activity activity, @ColorInt int color) {
setColor(activity, color, DEFAULT_STATUS_BAR_ALPHA);
}
public static void setColor(Activity activity, @ColorInt int color, @IntRange(from = 0, to = 255) int statusBarAlpha) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// 系統如果是5.0以上的走這裏
// 繪製一個背景透明的狀態欄,然後用StatusBarColor中的顏色再去填充狀態欄.
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
// 清除FLAG_TRANSLUCENT_STATUS
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// 這裏是設置狀態欄顏色
activity.getWindow().setStatusBarColor(calculateStatusColor(color, statusBarAlpha));
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// 系統如果是4.4走這裏
// FLAG_TRANSLUCENT_STATUS:設置狀態欄透明,並且爲全屏.
// 在4.4的系統中,這樣設置以後DecorView整個佈局會向上移動後和狀態欄重合,
// 所以下面會創建一個與狀態欄大小相同的佈局放入DecorView中,讓DecorView沒法向上移動與狀態欄重合.
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// 找到當前Activity的DecorView
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
// 獲取DecorView中自己創建的大小相同仿狀態欄View
View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
if (fakeStatusBarView != null) {
// 如果仿狀態欄View在DecorView中找到了
if (fakeStatusBarView.getVisibility() == View.GONE) {
fakeStatusBarView.setVisibility(View.VISIBLE);
}
// 設置這個仿狀態欄View背景色爲用戶希望的狀態欄顏色.
// calculateStatusColor():該方法用來計算顏色的.
fakeStatusBarView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
} else {
// 如果仿狀態欄View在DecorView中沒有找到,
// 那麼就創建這個仿狀態欄View,然後將它添加到DecorView中第0位置.
decorView.addView(createStatusBarView(activity, color, statusBarAlpha));
}
// 設置用戶佈局的paddingTop屬性以及繪製的區域.
setRootView(activity);
}
}
/**
* 設置根佈局參數
*/
private static void setRootView(Activity activity) {
// 找到承載用戶佈局的父容器View.
ViewGroup parent = (ViewGroup) activity.findViewById(android.R.id.content);
// 對該父容器中的子View遍歷
for (int i = 0, count = parent.getChildCount(); i < count; i++) {
View childView = parent.getChildAt(i);
if (childView instanceof ViewGroup) {
// 忽略用戶爲childView設置的padding屬性,將由系統爲該View設置paddingTop屬性,高度值爲狀態欄的高度.
childView.setFitsSystemWindows(true);
// 設置childView不在padding代表的區域中繪製.
((ViewGroup) childView).setClipToPadding(true);
}
}
}
/**
* 生成一個和狀態欄大小相同的半透明矩形條
*
* @param activity 需要設置的activity
* @param color 狀態欄顏色值
* @param alpha 透明值
* @return 狀態欄矩形條
*/
private static View createStatusBarView(Activity activity, @ColorInt int color, int alpha) {
// 繪製一個和狀態欄一樣高的矩形
View statusBarView = new View(activity);
// getStatusBarHeight() 獲取當前狀態欄的高度.
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
statusBarView.setLayoutParams(params);
// 設置仿狀態欄View的背景
statusBarView.setBackgroundColor(calculateStatusColor(color, alpha));
// 這一步是爲該View設置一個ID,方便到時候用這個ID找到該View.
statusBarView.setId(FAKE_STATUS_BAR_VIEW_ID);
return statusBarView;
}
}
至此,爲4.4版本和5.0以上版本的系統設置狀態欄的顏色就分析完成了,這裏做下總結:
- 4.4系統設置狀態欄顏色,首先設置狀態欄透明並且爲全屏,然後向
DecorView
中添加一個仿狀態欄的View,爲該View設置想要的顏色,然後爲用戶創建的佈局設置paddingTop屬性以及繪製的區域. - 5.0以上系統設置狀態欄顏色相對簡單,調用一些API就能做到.
將佈局延申到狀態欄
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// 5.0以上系統做法
// 繪製一個背景透明的狀態欄,然後用StatusBarColor中的顏色再去填充狀態欄.
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
// 爲狀態欄設置透明顏色
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
// 透明導航欄
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
// 清除這個標記,4.4採用這個標記
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// 視圖延伸至狀態欄區域,狀態欄上浮於視圖之上
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
} else {
// 4.4系統做法
// 設置狀態欄透明,並且爲全屏
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}