android4.4以上的狀態列背景和文字顏色的修改記錄
4.4以上
Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
先使用 FLAG_TRANSLUCENT_STATUS 設定狀態列透明
然後用一個期望的背景色view填充statusBar
同時使用 setFitsSystemWindows 讓標題欄下移,否則標題欄和狀態列會重疊
@RequiresApi(api = Build.VERSION_CODES.KITKAT) private static void setStatusBarBackground_V19(Activity activity, int color) { Window window = activity.getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); ViewGroup decorViewGroup = (ViewGroup) window.getDecorView(); View statusBarView = new View(window.getContext()); //獲取statusBar高度 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); //設定標題欄下移 ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0); rootView.setFitsSystemWindows(true); rootView.setClipToPadding(true); }
5.0以上
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
可以使用 setStatusBarColor 方法直接修改
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @RequiresApi(api = Build.VERSION_CODES.KITKAT) private static void setStatusBarBackground_V21(Activity activity, int color) { Window window = activity.getWindow(); //首先清除預設的FLAG_TRANSLUCENT_STATUS window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); window.setStatusBarColor(color); }
6.0以上(淺色背景的適配)
在6.0以上,谷歌新增了修改狀態列文字顏色的方法,當我們的狀態列顏色為淺色 或接近狀態列文字顏色 的時候,我們就可以把狀態列的文字改成深色。
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //修改為深色,因為我們把狀態列的背景色修改為主題色白色,預設的文字及圖示顏色為白色,導致看不到了。 activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); }
其他機型的適配(小米,魅族)
小米
小米手機的系統版本是在android6.0 以後的,使用系統的修改方式
即:
setSystemUiVisibility-> 修改狀態列文字顏色 setStatusBarColor -> 修改狀態列背景色
在其他版本 中,小米提供了自己的方法修改狀態列文字顏色,修改背景色使用系統的方法
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
static boolean MIUISetStatusBarLightMode(Activity activity, boolean darkmode) { boolean result = false; Class<? extends Window> clazz = activity.getWindow().getClass(); try { int darkModeFlag = 0; Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams"); Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE"); darkModeFlag = field.getInt(layoutParams); Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class); extraFlagField.invoke(activity.getWindow(), darkmode ? darkModeFlag : 0, darkModeFlag); result = true; } catch (Exception e) { e.printStackTrace(); } return result; }
//判斷是miui7以上的 private static boolean isMiUIV7OrAbove() { try { final Properties properties = new Properties(); properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop"))); String uiCode = properties.getProperty(KEY_MIUI_VERSION_CODE, null); if (uiCode != null) { int code = Integer.parseInt(uiCode); return code >= 5; } else { return false; } } catch (final Exception e) { return false; } }
//判斷是miui6以上的 private static boolean isMiUIV6OrAbove() { try { final Properties properties = new Properties(); properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop"))); String uiCode = properties.getProperty(KEY_MIUI_VERSION_CODE, null); if (uiCode != null) { int code = Integer.parseInt(uiCode); return code >= 4; } else { return false; } } catch (final Exception e) { return false; } }
魅族
魅族提供自己的方法修改狀態列文字顏色
狀態列背景色使用系統預設的
static boolean FlymeSetStatusBarLightMode(Activity activity, boolean darkmode) { boolean result = false; 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 (darkmode) { value |= bit; } else { value &= ~bit; } meizuFlags.setInt(lp, value); activity.getWindow().setAttributes(lp); result = true; } catch (Exception e) { e.printStackTrace(); } return result; }
//判斷魅族系統 private static boolean isFlymeV4OrAbove() { String displayId = Build.DISPLAY; if (!TextUtils.isEmpty(displayId) && displayId.contains("Flyme")) { String[] displayIdArray = displayId.split(" "); for (String temp : displayIdArray) { //版本號4以上,形如4.x. if (temp.matches("^[4-9]\\.(\\d+\\.)+\\S*")) { return true; } } } return false; }
貼下程式碼
public class StatusBarUtils { public static void setLightStatusBar(Activity activity) { final int white = ContextCompat.getColor(activity, R.color.white); final int gray = ContextCompat.getColor(activity, R.color.graymin); final int testColor=ContextCompat.getColor(activity,R.color.blue); if (isMiUIV7OrAbove()) { //設定狀態列文字黑色 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); //設定狀態列顏色 setStatusBarBackground_V21(activity, white); }else { MIUISetStatusBarLightMode(activity,true); setStatusBarBackground_V19(activity,white); } return; } else if (isMiUIV6OrAbove()) { MIUISetStatusBarLightMode(activity, true); setStatusBarBackground_V19(activity,white); return; } if (isFlymeV4OrAbove()){ FlymeSetStatusBarLightMode(activity,true); setStatusBarBackground_V19(activity,white); return; } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //api23+ 6.0以上的 //設定狀態列文字黑色 activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); //設定狀態列顏色 setStatusBarBackground_V21(activity, white); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //api21-235.0~6.0 //字型不能變色,所以statusBar顏色改成灰的 setStatusBarBackground_V21(activity, gray); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //api19-21 setStatusBarBackground_V19(activity, gray); } } @TargetApi(Build.VERSION_CODES.LOLLIPOP) @RequiresApi(api = Build.VERSION_CODES.KITKAT) private static void setStatusBarBackground_V21(Activity activity, int color) { Window window = activity.getWindow(); //首先清除預設的FLAG_TRANSLUCENT_STATUS window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); window.setStatusBarColor(color); } @RequiresApi(api = Build.VERSION_CODES.KITKAT) private static void setStatusBarBackground_V19(Activity activity, int color) { Window window = activity.getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 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); //設定標題欄下移 ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0); rootView.setFitsSystemWindows(true); rootView.setClipToPadding(true); } private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code"; private static boolean isMiUIV6OrAbove() { try { final Properties properties = new Properties(); properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop"))); String uiCode = properties.getProperty(KEY_MIUI_VERSION_CODE, null); if (uiCode != null) { int code = Integer.parseInt(uiCode); return code >= 4; } else { return false; } } catch (final Exception e) { return false; } } private static boolean isMiUIV7OrAbove() { try { final Properties properties = new Properties(); properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop"))); String uiCode = properties.getProperty(KEY_MIUI_VERSION_CODE, null); if (uiCode != null) { int code = Integer.parseInt(uiCode); return code >= 5; } else { return false; } } catch (final Exception e) { return false; } } private static boolean isFlymeV4OrAbove() { String displayId = Build.DISPLAY; if (!TextUtils.isEmpty(displayId) && displayId.contains("Flyme")) { String[] displayIdArray = displayId.split(" "); for (String temp : displayIdArray) { //版本號4以上,形如4.x. if (temp.matches("^[4-9]\\.(\\d+\\.)+\\S*")) { return true; } } } return false; } static boolean MIUISetStatusBarLightMode(Activity activity, boolean darkmode) { boolean result = false; Class<? extends Window> clazz = activity.getWindow().getClass(); try { int darkModeFlag = 0; Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams"); Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE"); darkModeFlag = field.getInt(layoutParams); Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class); extraFlagField.invoke(activity.getWindow(), darkmode ? darkModeFlag : 0, darkModeFlag); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } static boolean FlymeSetStatusBarLightMode(Activity activity, boolean darkmode) { boolean result = false; 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 (darkmode) { value |= bit; } else { value &= ~bit; } meizuFlags.setInt(lp, value); activity.getWindow().setAttributes(lp); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } private static int getStatusBarHeight(Context context) { int statusBarHeight = 0; Resources res = context.getResources(); int resourceId = res.getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { statusBarHeight = res.getDimensionPixelSize(resourceId); } return statusBarHeight; } }
--
參考文件: