About Android Immersion Status Bar Greying

Preface

The immersive status bar is almost the current Android app tag. Usually we call the setStatusBarTintResource() method to set the status bar.
A color or transparency. But today, in the development of Android 7.0 environment, even if the status bar is set to white, the actual display of the color.
It's grey, like this.

Cause analysis

Because this is the phenomenon that Android 7.0 will appear, it can be concluded that 7.0 should be the operation of the status bar to do so, haha. Let's go through the cane and touch the melon.
Take a look at the source code and see how Android 6.0 differs from 7.0. DecorView is the internal class of Phone Windows in 6.0.
In 7.0, DecorView is a separate class with new attributes mSemiTransparentStatusBarColor. Find his code:
DecorView(Context context, int featureId, PhoneWindow window,WindowManager.LayoutParams params) {
        super(context);
        ......
        mForceWindowDrawsStatusBarBackground = context.getResources().getBoolean(
                R.bool.config_forceWindowDrawsStatusBarBackground)
                && context.getApplicationInfo().targetSdkVersion >= N;
                //Setting default gray
        mSemiTransparentStatusBarColor = context.getResources().getColor(
                R.color.system_bar_background_semi_transparent, null /* theme */);
        ......
    }
private int calculateStatusBarColor() {
    int flags = mWindow.getAttributes().flags;
    return (flags & FLAG_TRANSLUCENT_STATUS) != 0 ? mSemiTransparentStatusBarColor
                : (flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0 ? mWindow.mStatusBarColor : Color.BLACK;
}
The calculateStatusBarColor method calculates the color value of the status bar, where FLAG_TRANSLUCENT_STATUS is a transparent identifier if flags
 If FLAG_TRANSLUCENT_STATUS is equal to or not equal to 0, the default gray value mSemiTransparentStatusBarColor is chosen. this
 The calculateStatusBarColor method is called in the updateColorViews method, and the updateColorViews method is onWindows DragResizeStart,
On Windows DragResizeEnd and other methods, we can see why the status bar settings do not work. This background color is calculated dynamically.
So just change the mSemiTransparentStatusBarColor variable value to transparent, ok ay, laugh:)

Solutions

Get the mSemiTransparentStatusBarColor attribute by reflection, and then achieve full transparency
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
    try {
        Class decorViewClazz = Class.forName("com.android.internal.policy.DecorView");
        Field field = decorViewClazz.getDeclaredField("mSemiTransparentStatusBarColor");
        field.setAccessible(true);  
        field.setInt(getWindow().getDecorView(), Color.TRANSPARENT);  //Set transparency
    } catch (Exception e) {}
}

Note: This code needs to be invoked before the setContentView method.

ok, it's done. Run up and watch.

Issues of Attention

Some people set the status bar to white, which will conflict with the font color of the status bar, causing nothing to be seen.
You can set the font color of the status bar to black in the following way
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

Keywords: Android Windows Attribute

Added by seed on Thu, 16 May 2019 05:18:30 +0300