Preface:
Android development, for the status bar modification, it is not friendly, there is no API to use, not as convenient as ios. But UI likes to be ios only. No way. All kinds of source code, write reflection. It really hurts.
Requirement scenarios:
When the Toolbar and status bar need to be white or light-colored (e.g., simple book), the status bar will be hard to read due to the light-style Theme, font, and ICONS that are white. If I change it to black, it will be very harmonious.
1. Modify the status bar color:
To change the color of the statusbar, check out this article portal: achieving the statusbar gradient effect is actually quite simple
What the portal does:
This method achieves color-changing status bar with no black background.
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — line — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — –
Using the full screen mode to achieve the following effect (QQ effect):
Clear translucent black background.
My mobile phone is Huawei with system 7.0
2. Modify the status bar font:
General tool classes:
Public class StatusBarUtil {/** ** Sets the black font icon in the status bar. * For MIUIV and Flyme versions 4.4 and later, and other Android versions 6.0 and laterreturnPublic static int getStatusBarLightMode(Window Window) {int result = 0;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (MIUISetStatusBarLightMode(window, true)) {
result = 1;
} else if (FlymeSetStatusBarLightMode(window, true)) {
result = 2;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
result = 3;
} else {//5.0
}
}
returnresult; } /** * Set the black font icon in the status bar when the system type is known. * For MIUIV 4.4 or later, Flyme 6.0 or later, other Android */ public static voidsetStatusBarLightMode(Window window) {
int type = getStatusBarLightMode(window);
if (type == 1) {
MIUISetStatusBarLightMode(window, true);
} else if (type == 2) {
FlymeSetStatusBarLightMode(window, true);
} else if (type == 3) {
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else*/ public static void StatusBarDarkMode(Window Window) {inttype = getStatusBarLightMode(window);
if (type == 1) {
MIUISetStatusBarLightMode(window, false);
} else if (type == 2) {
FlymeSetStatusBarLightMode(window, false);
} else if (type== 3) { window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); } /** * Set the status bar icon to dark color and Meizu specific text style * can be used to determine whether the Flyme user ** @param window needs to be set * @param dark whether the status bar font and icon color is set to dark * @returnBoolean returns successfully executedtrue
*/
public static boolean FlymeSetStatusBarLightMode(Window window, boolean dark) {
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 (dark) {
value |= bit;
} else {
value &= ~bit;
}
meizuFlags.setInt(lp, value);
window.setAttributes(lp);
result = true;
} catch (Exception e) {
}
}
returnresult; } /** * To set the status bar font icon to dark color, MIUIV6 above ** @param window to set the window * @param dark Whether to set the status bar font and icon color to dark color * @returnBoolean returns successfully executedtrue
*/
public static boolean MIUISetStatusBarLightMode(Window window, boolean dark) {
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(dark) { extraFlagField.invoke(window, darkModeFlag, darkModeFlag); // Status bar transparent and black font}else{ extraFlagField.invoke(window, 0, darkModeFlag); // Clear black text} result =true;
} catch (Exception e) {
}
}
returnresult; }}Copy the code
Use:
StatusBarUtil.setStatusBarLightMode(getWindow());
Copy the code
Effect:
Problems:
1. The statusbar background color has changed to colorPrimaryDark by default, but my configuration is white (see the code at the end).
Analyze the reasons:
setSystemUiVisibility() will refresh the view's property configuration. Since statusbar uses the colorPrimaryDark property by default. So the color will go back to the default colorCopy the code
In this case, the method of setting the background in step 1 is invalid.
private void initStatusBar() {
if (statusBarView == null) {
int identifier = getResources().getIdentifier("statusBarBackground"."id"."android");
statusBarView = getWindow().findViewById(identifier);
}
if (statusBarView != null) {
statusBarView.setBackgroundResource(MVPConfig.statusDrawable);
}
}
Copy the code
Reason: When the passed resiD is the same, the background color will not be set again.
Solutions:
private void initStatusBar() {
if (statusBarView == null) {
int identifier = getResources().getIdentifier("statusBarBackground"."id"."android");
statusBarView = getWindow().findViewById(identifier);
}
if(statusBarView ! = null) { statusBarView.setBackgroundDrawable(null); // Set the background to null before setting; //statusBarView.setBackgroundResource(0); / / this can also be statusBarView. SetBackgroundResource (MVPConfig. StatusDrawable); }}Copy the code
Modified effect:
Iii. Complete code:
####1.MvpConfig
public class MVPConfig {
public static int statusDrawable;
public static int toolbarBackgroundColor;
public static int toolbarBackgroundDrawable;
public static int backDrawable;
public static boolean isStatusBarLight;
public static void setStatusbarDrawable(@DrawableRes int statusDraw) {
statusDrawable = statusDraw;
}
public static boolean isStatusBar() {
return statusDrawable > 0;
}
public static void setToolbarDrawable(int toolbarBackgroundDrawable) {
MVPConfig.toolbarBackgroundDrawable = toolbarBackgroundDrawable;
}
public static void setBackDrawable(int backDrawable) {
MVPConfig.backDrawable = backDrawable;
}
public static void setIsStatusBarLight(boolean isStatusBarLight) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
MVPConfig.statusDrawable = Color.parseColor("#33ffffff");
}
MVPConfig.isStatusBarLight = isStatusBarLight;
}
Copy the code
2. In the Application
@Override
public void onCreate() {
super.onCreate();
MVPConfig.setToolbarDrawable(R.color.white);
MVPConfig.setStatusbarDrawable(R.color.white);
MVPConfig.setBackDrawable(R.drawable.back);
MVPConfig.setIsStatusBarLight(true);
}
Copy the code
3.BaseActivity
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Delay loading data. Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
@Override
public boolean queueIdle() {
if (isStatusBarLight()) {
StatusBarUtil.setStatusBarLightMode(getWindow());
}
if (isStatusBar()) {
initStatusBar();
getWindow().getDecorView().addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { initStatusBar(); }}); } mPresenter.initData();return false; }}); } private voidinitStatusBar() {
if (statusBarView == null) {
int identifier = getResources().getIdentifier("statusBarBackground"."id"."android");
statusBarView = getWindow().findViewById(identifier);
}
if(statusBarView ! = null) {if(isStatusBarLight()) { statusBarView.setBackgroundDrawable(null); } statusBarView.setBackgroundResource(MVPConfig.statusDrawable); }} // Subclasses override this method to control whether to change statusbar protected BooleanisStatusBar() {
returnMVPConfig.isStatusBar(); } // Subclasses override this method to control whether they need to change the statusbar font color protected BooleanisStatusBarLight() {
return MVPConfig.isStatusBarLight;
}
Copy the code
Iv. Supplementary:
- Under 6.0,5.0 native system can not change the font color, used a more clever way, set to translucent gray.
public static void setStatusBarLightMode(Window window) {
int type = getStatusBarLightMode(window);
if (type == 1) {
MIUISetStatusBarLightMode(window, true);
} else if (type == 2) {
FlymeSetStatusBarLightMode(window, true);
} else if (type == 3) {
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else{/ / 5.0if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
MVPConfig.statusDrawable = Color.parseColor("#33ffffff"); }}}Copy the code
- Since you modify the background of the StatusBarView in the Window directly, and frgament depends on the Activity, the statusbar is not very useful when the Activity and Fragment jump directly. For example, if the activity is blue, the fragment needs to be white, and the fragment needs to change the color of the status bar through the window. It’s a bit of a problem.
Your love and reply is my biggest motivation – –