Android Development - Setting System Status Bar Colors

How to Realize

To set the color of the system status bar, you need to at least set the color of the system status bar. Android More than 4.4.2 (API 19). This is because, below this version, there is no API to help us achieve. So how to set it up?

Android 4.4.2

Realization

android 4.4.2 adds a feature that allows the system status bar to be translucent. There are two ways to set it. One is by adding the following attributes to the theme style:

<item name="android:windowTranslucentStatus">true</item>
  • 1

The second is through Java Settings in the code, that is, the following code:

Window window = activity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  • 1
  • 2

After setting the system status bar to translucent, we can add a View to the decorView of the Windows Window to make it the same size as the system status bar, and then set the background of the view to achieve the effect of changing the color of the status bar. The code is as follows:

        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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

The method code for obtaining the height of the status bar is as follows:

    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;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Then use the above code in our Activity's onCreate method.

Problems and Solutions

But after using it, we will find that the layout content of our Activity goes up to the status bar and is covered by the status bar and the Action Bar. The solution is simple, just set the following attributes in the root element of our layout file:

android:fitsSystemWindows="true"
  • 1

It means that the layout is embedded, that is to say, it will leave space for the status bar and so on, so that our layout will return to normal.  
But the problem is, if you have dozens of Activities, it's frustrating to change the layout file for each one. So, after some searching, we seem to have found the answer. That is, by configuring this property in the Application topic. Unfortunately, we found that after doing so, our Toast display was abnormal, and its text would go beyond the black background.  
But it doesn't matter. We still have solutions. That is, after setContentView(), add the following code:

    ViewGroup mContentView = (ViewGroup) window.findViewById(Window.ID_ANDROID_CONTENT);
    View mChildView = mContentView.getChildAt(0);
    if (mChildView != null) {
        //Note that instead of setting up FitsSystem Windows for ContentView, you set up the first sub-View for ContentView. Reserve space for System View.
        mChildView.setFitsSystemWindows(fitSystemWindows);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

That is to find the View of our Activity's content in JAVA code and set this property to it.

Android 5.0.1

Since Android 5.0.1 (API 21), the government has introduced a number of features for us, including an important approach:

window.setStatusBarColor(color);
  • 1

It seems very exciting. To make it work, you must set a FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS attribute and ensure that FLAG_TRANSLUCENT_STATUS is not set.  
Well, let's do it:

    Window window = activity.getWindow();
    //Cancel the transparent status bar so that the ContentView content no longer overrides the status bar
    window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    //You need to set this flag to call setStatusBarColor to set the status bar color
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
    //Set the status bar color
    window.setStatusBarColor(color);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Unfortunately, the P7 on my hands didn't work. It is said that the color PrimaryDark property is to be set in the theme, but after I tried it, I found that the status bar was not set to the color I wanted, and it might be displayed in other colors. So I didn't use this method in the end.

Android 6.0

Android 6.0 sets the color of the status bar in the same way as above. Fortunately, its settings are valid. The code is the same as above:

        //Cancel the transparent status bar so that the ContentView content no longer overrides the status bar
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        //You need to set this flag to call setStatusBarColor to set the status bar color
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        //Set the status bar color
        window.setStatusBarColor(color);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Unlike API 19, which sets the status bar translucent and adds a View, the color of the status bar is set directly here, so if our status bar is set to white, the same white system state above will not be seen. However, the 6.0 API adds an attribute to solve this problem. That is, if the color of the status bar we set is close to white, we can add the following attributes to the theme:

<item name="android:windowLightStatusBar">true</item>
  • 1

In this way, the text icons of the system state will turn black, as in the third picture we saw at the beginning.  
The JAVA code is set as follows:

    View decor = window.getDecorView();
    int ui = decor.getSystemUiVisibility();
    if (lightStatusBar) {
        ui |=View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
    } else {
        ui &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
    }
    decor.setSystemUiVisibility(ui);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

How to realize it quickly

So, do you really want to write so much code in the project according to different system versions? Also change the style file? Create different style files for different system versions to achieve this function?  
It's totally unnecessary, because I've already packaged it. You only need two steps to complete it.  
The following dependencies are declared in the build.gradle of the project:

    compile 'com.githang:status-bar-compat:0.3'
  • 1

Add the following code in your Activity (preferably after setContentView() is called):

    StatusBarCompat.setStatusBarColor(this, color, lightStatusBar);
  • 1

No version, no fitsSystem Windows, no status bar set to white, no system state, and compatible with MIUI and Flyme. So, when you look at the pure color status bar on the 6.0 mobile phone, do you think that QQ on the 6.0 mobile phone is still using the semi-transparent status bar with shadows to achieve the effect of setting the status bar color is ugly?  

Epilogue

  • For the above items, see: https://github.com/msdx/status-bar-compat
  • If you have any questions, please mention them here: https://github.com/msdx/status-bar-compat/issues
  • I encountered a failure in setting the status bar color in 5.0.1. If you can solve it successfully, you are welcome to mention Pull Request on Github.
  • The code in this project is hardly my original. I'm the porter of code snippets and I organize them together in a better way that I think and optimize them.

Keywords: Android Java Windows github

Added by todd2006 on Sat, 08 Jun 2019 02:44:23 +0300