現(xiàn)在沉浸式狀態(tài)欄基本都成為產(chǎn)品主流樣式了瓤逼。但對(duì)于google官方提供的API對(duì)于狀態(tài)欄的顏色設(shè)置是4.4版本才推出毅人,所以我們也只能適配4.4及以上版本闯狱。但在4.4到5.0的時(shí)候只能通過(guò)設(shè)置狀態(tài)欄透明票堵,然后手動(dòng)添加偽狀態(tài)欄來(lái)進(jìn)行修改狀態(tài)欄顏色,對(duì)于5.0以上可以通過(guò)修改狀態(tài)欄顏色即可偷溺。我們都知道蹋辅,對(duì)于Activity我們通過(guò)setContentView方法添加的我們需要顯示的xlm布局文件,其實(shí)是添加在decoview下面的content(其實(shí)是一個(gè)FrameLayout)里面挫掏。對(duì)于4.4~5.0之間的版本我們創(chuàng)建的偽狀態(tài)欄就添加在decoview里面侦另。先看看效果:
看效果還行,并且以適配Drawlayout,F(xiàn)ragment對(duì)狀態(tài)欄的修改褒傅。
如果對(duì)于文字描敘不太清楚弃锐,可看看下面實(shí)現(xiàn)方式布局圖:
廢話不多,開擼殿托、開擼霹菊。
public class StatusBarUtil {
private static final int FAKE_STATUS_BAR_VIEW_ID = R.id.status_bar_util_fake_status_bar_view;
public static void setStatusBarColorRes(Activity activity, @ColorRes int color){
setStatusBarColor(activity, activity.getResources().getColor(color));
}
public static void setStatusBarColor(Activity activity, @ColorInt int color) {
DrawerLayout drawerLayout = findDrawerLayout(activity);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
if (drawerLayout == null) {
if (activity.getWindow().getStatusBarColor() == Color.TRANSPARENT) {
setContentLayoutParamsOfTop(activity, getStatusBarHeight(activity));
}
activity.getWindow().setStatusBarColor(color);
} else {
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
setDrawLayouterStatusBarColor(activity, drawerLayout, color);
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
if (drawerLayout == null) {
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
if (fakeStatusBarView != null) {
if (fakeStatusBarView.getVisibility() == View.GONE) {
fakeStatusBarView.setVisibility(View.VISIBLE);
}
fakeStatusBarView.setBackgroundColor(color);
} else {
decorView.addView(createStatusBarView(activity, color));
}
setContentLayoutParamsOfTop(activity, getStatusBarHeight(activity));
setRootView(activity);
} else {
setDrawLayouterStatusBarColor(activity, drawerLayout, color);
}
}
}
public static void setStatusBarTraslucent(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
setTransparentForWindow(activity);
setContentLayoutParamsOfTop(activity, 0);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
clearPreviousSetting(activity);
}
DrawerLayout drawerLayout = findDrawerLayout(activity);
if (drawerLayout != null) {
setDrawerLayoutProperty(drawerLayout);
}
}
}
private static void setDrawLayouterStatusBarColor(Activity activity, DrawerLayout drawerLayout, @ColorInt int color) {
ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
View fakeStatusBarView = contentLayout.findViewById(FAKE_STATUS_BAR_VIEW_ID);
if (fakeStatusBarView != null) {
if (fakeStatusBarView.getVisibility() == View.GONE) {
fakeStatusBarView.setVisibility(View.VISIBLE);
}
fakeStatusBarView.setBackgroundColor(color);
} else {
drawerLayout.removeView(contentLayout);
LinearLayout linearLayout = new LinearLayout(activity);
linearLayout.setLayoutParams(new DrawerLayout.LayoutParams(DrawerLayout.LayoutParams.MATCH_PARENT, DrawerLayout.LayoutParams.MATCH_PARENT));
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.addView(createStatusBarView(activity, color));
linearLayout.addView(contentLayout);
drawerLayout.addView(linearLayout, 0);
}
setDrawerLayoutProperty(drawerLayout);
}
private static void clearPreviousSetting(Activity activity) {
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
if (fakeStatusBarView != null) {
decorView.removeView(fakeStatusBarView);
}
}
private static void setContentLayoutParamsOfTop(Activity activity, int top) {
ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
rootView.setPadding(0, top, 0, 0);
}
private static void setTransparentForWindow(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
activity.getWindow()
.getDecorView()
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
activity.getWindow()
.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
private static DrawerLayout findDrawerLayout(Activity activity) {
ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0);
if (rootView instanceof DrawerLayout) {
return (DrawerLayout) rootView;
}
return null;
}
private static void setDrawerLayoutProperty(DrawerLayout drawerLayout) {
ViewGroup drawer = (ViewGroup) drawerLayout.getChildAt(1);
drawerLayout.setFitsSystemWindows(false);
drawer.setFitsSystemWindows(false);
}
@TargetApi(Build.VERSION_CODES.M)
public static void setLightMode(Activity activity) {
setMIUIStatusBarDarkIcon(activity, true);
setMeizuStatusBarDarkIcon(activity, true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
}
@TargetApi(Build.VERSION_CODES.M)
public static void setDarkMode(Activity activity) {
setMIUIStatusBarDarkIcon(activity, false);
setMeizuStatusBarDarkIcon(activity, false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
}
private static void setRootView(Activity activity) {
ViewGroup parent = activity.findViewById(android.R.id.content);
for (int i = 0; i < parent.getChildCount(); i++) {
View childView = parent.getChildAt(i);
if (childView instanceof ViewGroup) {
childView.setFitsSystemWindows(true);
((ViewGroup) childView).setClipToPadding(true);
}
}
}
private static View createStatusBarView(Activity activity, @ColorInt int color) {
View statusBarView = new View(activity);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
statusBarView.setLayoutParams(params);
statusBarView.setBackgroundColor(color);
statusBarView.setId(FAKE_STATUS_BAR_VIEW_ID);
return statusBarView;
}
private static int getStatusBarHeight(Context context) {
// 獲得狀態(tài)欄高度
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
return context.getResources().getDimensionPixelSize(resourceId);
}
/**
* 修改 MIUI V6 以上狀態(tài)欄顏色
*/
private static void setMIUIStatusBarDarkIcon(@NonNull Activity activity, boolean darkIcon) {
Class<? extends Window> clazz = activity.getWindow().getClass();
try {
Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
int darkModeFlag = field.getInt(layoutParams);
Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
extraFlagField.invoke(activity.getWindow(), darkIcon ? darkModeFlag : 0, darkModeFlag);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 修改魅族狀態(tài)欄字體顏色 Flyme 4.0
*/
private static void setMeizuStatusBarDarkIcon(@NonNull Activity activity, boolean darkIcon) {
try {
WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
Field meizuFlags = WindowManager.LayoutParams.class.getDeclaredField("meizuFlags");
darkFlag.setAccessible(true);
meizuFlags.setAccessible(true);
int bit = darkFlag.getInt(null);
int value = meizuFlags.getInt(lp);
if (darkIcon) {
value |= bit;
} else {
value &= ~bit;
}
meizuFlags.setInt(lp, value);
activity.getWindow().setAttributes(lp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
為了在Fragment切換時(shí)修改同一Activity的狀態(tài)欄,所以我們得給偽狀態(tài)欄設(shè)置id(及在values目錄下新建一資源文件ids)
<item name="status_bar_util_fake_status_bar_view" type="id" />