origin

I have a kind of complex for Android status bar and navigation bar, before I do Android development, I like to make status bar and navigation bar through some Xposed plug-in color or transparent, to eliminate the ugly two black bar.

After doing Android development, I even wrote two articles (the ultimate solution of transparent status bar and navigation bar, the true ultimate solution of Android status bar and navigation bar) to analyze the implementation of various effects of Android 4.4 status bar and navigation bar. A library, UltimateBar, is also open sourced.

However, with the growth of my own technology, I feel more and more that the library design is not good, there are many defects, even to maintain the situation of immobile. For example, I am often asked about issues like:

Both of these problems, it is actually the same question, is mainly because of the status bar and navigation bar Settings coupled together, lead to modify the status bar, a navigation bar will also be affected, and, of course, I didn’t mean to put their coupling together, just want to realize the function of many complex forced to work on, but now I have completely solve this problem, will say to the behind.

For these reasons, I recently created a new library named UltimateBarX, which borrowed its name from Google’s “AndroidX” library. Google’s previous Support library was too confusing, so I created a new one named “AndroidX”. It’s more or less similar.

Let’s take a look at how this library is used and how it works.

fromfitsSystemWindowsMethods about

There’s a method in the View called setFitsSystemWindows. What does this do? If you set setFitsSystemWindows(true) to the outermost layer of the contentView when setting the Activity to full screen, Then the contentView won’t invade the status bar and the navigation bar, or it would. What does that mean? For example, on Android 5.0 and above, if you do the following in your Activity

int flag = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
getWindow().getDecorView().setSystemUiVisibility(flag);
getWindow().setStatusBarColor(Color.parseColor("# 66000000"));
getWindow().setNavigationBarColor(Color.parseColor("# 66000000"));
Copy the code

You’ll see something like this

If I were to add to that

findViewById(R.id.contentView).setFitsSystemWindows(true);
Copy the code

It’s going to look something like this

The two diagrams above have graphically illustrated the difference between intrusive and non-intrusive. The setFitsSystemWindows(True) method applies to both the status bar and the navigation bar simultaneously, so either the status bar or the navigation bar are accessed at all. What if I now asked the layout to invade the status bar and not the navigation bar, which is also possible, just remove view.system_UI_flag_layout_hide_navigation from the code above, i.e.

int flag = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
getWindow().getDecorView().setSystemUiVisibility(flag);
getWindow().setStatusBarColor(Color.parseColor("# 66000000"));
findViewById(R.id.contentView).setFitsSystemWindows(false);
Copy the code

This allows you to set only the status bar and leave the navigation bar untouched. Similarly, if you want the layout to invade the navigation bar and leave the status bar untouched, you just need to

int flag = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
getWindow().getDecorView().setSystemUiVisibility(flag);
getWindow().setNavigationBarColor(Color.parseColor("# 66000000"));
findViewById(R.id.contentView).setFitsSystemWindows(false);
Copy the code

It seems as if there is no problem, can solve a variety of situations, however, if demand now is such, first of all, just enter the Activity, let the layout in the navigation bar, then click a button, when the navigation bar was unchanged, at the same time, let the layout in the status bar, if still use the above methods, This causes the navigation bar to be restored to its original state, as shown in the figure

The setSystemUiVisibility method will be used only the last time it is used, and all previous calls will be overwritten by the last time it is used. One way to resolve this problem is to save the status and navigation of the current Activity. Reset the setSystemUiVisibility parameter according to the saved state to ensure that the effect previously set is not affected, but this operation is too cumbersome, I chose another very simple method.

The core principles of UltimateBarX

When setting the status bar or navigation bar for the first time, let the layout invade the status bar and navigation bar for whatever effect you want, and then set the topPadding and bottomPadding of the decorView depending on whether you want to invade, as described above. You can make the layout invade both the status bar and the navigation bar when you first enter the Activity. Then set a topPadding status bar height to the decorView so that the layout does not invade the status bar. All you need to do is set the topPadding of the decorView to 0 again, leaving the navigation bar alone and saving the state of the previous navigation bar.

The use of the UltimateBarX

UltimateBarX is also very simple to use. This time I spent a lot of time thinking about how to make methods easier to call and maintain in the future. First add it to build.gradle

dependencies {
    implementation 'com. Zackratos. Ultimatebarx: ultimatebarx: while'
}
Copy the code

If you need to set the state, you can do so in the Activity

UltimateBarX.create(UltimateBarX.STATUS_BAR)        // Set the status bar
    .fitWindow(true)                                // Whether the layout invades the status bar (true not, false invades)
    .bgColor(Color.BLACK)                           // Status bar background color (color value)
    .bgColorRes(R.color.deepSkyBlue)                // Status bar background color (resource ID)
    .bgRes(R.drawable.bg_gradient)                  // Status bar background drawable
    .light(false)                                   // Light mode (status bar font gray Android 6.0 or above support)
    .apply(this);
Copy the code

BgRes > bgColor > bgColorRes (bgRes > bgColor > bgColorRes) Create “UltimateBarX.NAVIGATION_BAR”. The status bar and navigation bar are set independently of each other.

If you want to implement the requirements described above, you only need to do so when you first enter your Activity

UltimateBarX.create(UltimateBarX.NAVIGATION_BAR)
    .fitWindow(false)
    .bgColor(Color.parseColor("# 66000000"))
    .apply(this);
Copy the code

Set the layout to invade the navigation bar, then click the button to let the layout invade the status bar, just

UltimateBarX.create(UltimateBarX.STATUS_BAR)
    .fitWindow(false)
    .bgColor(Color.parseColor("# 66000000"))
    .apply(this);
Copy the code

aboutlightmethods

There is a light method that sets the light mode of the status bar or navigation bar. When the light mode is true, the status bar text will turn gray, and the corresponding navigation bar buttons will turn gray. There is a problem here. To set the light mode, you need to call the setSystemUiVisibility method in the decorView. This means that the light mode needs to be saved. If not, the first time you set the status bar to light mode and the second time you set the navigation bar, The status bar’s light mode is cleared, as explained earlier.

To make it less intrusive, you can use a singleton to store the light state of each Activity’s status bar and navigation bar. This creates another problem. When the Activity exits, the current Activity object must be removed from the singleton. Add an invisible Fragment to your Activity. When the Fragment’s onDestroy method is called, The Activity’s onDestroy is called, that is, the Activity exits.

Lifecycle is a tool that can be used to monitor the Lifecycle of activities and fragments without invading them. This is done with Lifecycle. Very conveniently, Lifecycle is implemented by adding an internal Fragment to listen on.

The last

Principle and usage are about the same, finally post again UltimateBarX address, I hope you pay more attention to, a lot of star, fork, raise issues, raise PR, also welcome to communicate with me

Github.com/Zackratos/U…