如何修改狀態列Statusbar(SystemUI)圖示和字型顏色
阿新 • • 發佈:2018-12-31
前言
由於公司專案的歡迎頁是白色的,,修改狀態列顏色後,導致狀態列的白色字型完全被覆蓋了,聯想到之前在QQ、UC等一些app上都見到過狀態列的字型是深色的,想著,,必定有解決的方案。於是,有了本篇blog。
參考
下面是我在網上找到的兩篇文章
解決方案
MIUI
public class MIUIHelper implements IHelper { /** * 設定狀態列字型圖示為深色,需要MIUI6以上 * * @param isFontColorDark 是否把狀態列字型及圖示顏色設定為深色 * @return boolean 成功執行返回true */ @Override public boolean setStatusBarLightMode(Activity activity, boolean isFontColorDark) { Window window = activity.getWindow(); boolean result = false; if (window != null) { Class clazz = window.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); if (isFontColorDark) { extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//狀態列透明且黑色字型 } else { extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字型 } result = true; } catch (Exception e) { e.printStackTrace(); } } return result; } }
flyme4+
public class FlymeHelper implements IHelper { /** * 設定狀態列圖示為深色和魅族特定的文字風格 * 可以用來判斷是否為Flyme使用者 * * @param isFontColorDark 是否把狀態列字型及圖示顏色設定為深色 * @return boolean 成功執行返回true */ @Override public boolean setStatusBarLightMode(Activity activity, boolean isFontColorDark) { Window window = activity.getWindow(); boolean result = false; if (window != null) { try { WindowManager.LayoutParams lp = window.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 (isFontColorDark) { value |= bit; } else { value &= ~bit; } meizuFlags.setInt(lp, value); window.setAttributes(lp); result = true; } catch (Exception e) { e.printStackTrace(); } } return result; } }
android6.0+
public class AndroidMHelper implements IHelper { /** * @return if version is lager than M */ @Override public boolean setStatusBarLightMode(Activity activity, boolean isFontColorDark) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (isFontColorDark) { // 沉浸式 // activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); //非沉浸式 activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); } else { //非沉浸式 activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); } return true; } return false; } }
2.style屬性設定
<!--直接生效,狀態列文字顏色變成黑色,非沉浸式-->
<item name="android:windowLightStatusBar">true</item>
public class Helper {
@IntDef({
OTHER,
MIUI,
FLYME,
ANDROID_M
})
@Retention(RetentionPolicy.SOURCE)
public @interface SystemType {
}
public static final int OTHER = -1;
public static final int MIUI = 1;
public static final int FLYME = 2;
public static final int ANDROID_M = 3;
/**
* 設定狀態列黑色字型圖示,
* 適配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
*
* @return 1:MIUI 2:Flyme 3:android6.0
*/
public static int statusBarLightMode(Activity activity) {
@SystemType int result = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (new MIUIHelper().setStatusBarLightMode(activity, true)) {
result = MIUI;
} else if (new FlymeHelper().setStatusBarLightMode(activity, true)) {
result = FLYME;
} else if (new AndroidMHelper().setStatusBarLightMode(activity, true)) {
result = ANDROID_M;
}
}
return result;
}
/**
* 已知系統型別時,設定狀態列黑色字型圖示。
* 適配4.4以上版本MIUI6、Flyme和6.0以上版本其他Android
*
* @param type 1:MIUI 2:Flyme 3:android6.0
*/
public static void statusBarLightMode(Activity activity, @SystemType int type) {
statusBarMode(activity, type, true);
}
/**
* 清除MIUI或flyme或6.0以上版本狀態列黑色字型
*/
public static void statusBarDarkMode(Activity activity, @SystemType int type) {
statusBarMode(activity, type, false);
}
private static void statusBarMode(Activity activity, @SystemType int type, boolean isFontColorDark) {
if (type == MIUI) {
new MIUIHelper().setStatusBarLightMode(activity, isFontColorDark);
} else if (type == FLYME) {
new FlymeHelper().setStatusBarLightMode(activity, isFontColorDark);
} else if (type == ANDROID_M) {
new AndroidMHelper().setStatusBarLightMode(activity, isFontColorDark);
}
}
}
本方案適配一下系統
- android6.0+
- MIUI6
- flyme4+
據說:適配淺色狀態列深色字型的時候發現底層版本為Android6.0.1的MIUI7.1系統不支援View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR設定,還是得用MIUI自己的深色字型方法。所以,這裡先適配MIUI跟flyme,再適配6.0,當然了,如果使用可以直接獲取系統名,根據字串判斷,也可以先6.0在MIUI,但是這個不靠譜。還不如直接在6的系統上統一全配置上
下面這個Sample是github上 MIUI的
當前例子只有小米和魅族手機開放了可以改變狀態列字型顏色的API,本截圖是小米4 MIUI7 Android6.0.1手機
Sample來源
https://github.com/DyncKathline/ChangeStatusColor-Android