preface

NavigationBar is the virtual navigation button at the bottom of the phone, common on Huawei and Xiaomi phones;

Android status bar processing and navigation bar processing is very similar, so the article mainly introduces the status bar processing, need to understand the navigation bar can be compared to the status bar processing code to understand, code has been provided in the Andme library;

Android status bar is very important for the entire App, which directly affects the display effect of the App. There are also a lot of relevant articles and third-party libraries on the market, but the quality is uneven and the code differentiation is serious, which is easy to make everyone confused. Even some libraries with relatively high STAR, their readability and quality seem to need to be improved;

In addition, I had done some understanding of the content of this section before, and I also needed to support the processing of status bar and navigation bar when REconstructing Andme this time. However, I found that what I had done before had disappeared, as if I knew nothing about it. As the saying goes, good memory is better than bad writing, close-up of this article in order to understand the relevant modules again in the future can be used as a reference;

The development of status bar has gone through several stages. It is impossible to operate the status bar before 4.4. Some domestic manufacturers may provide relevant functions to support it. 4.4 From the beginning of the official provision of bar status bar related operations, 5.0 has been improved, 6.0 has been supplemented, so we mainly talk about 4.4, 5.0, 6.0 three stages.

4.4

4.4 version of the status bar function is not very perfect, and the current 4.4 version of the mobile phone market share is not high, based on these two points, personal advice can give up 4.4 version of the status bar support.

4.4 From the beginning, two concepts of transparent system status bar and immersive full-screen mode are officially provided. The link of official information is only related to the status bar (in fact, the status bar is closely related to immersion).

In simple terms, this version offers, layout and content can be extended to the bottom of the status bar (that is, the status bar cover layout content), in addition there is no other, now on the market of the 7788 razzle dazzle function support, are implemented through the secondary processing, it is so, the multifarious, quality is uneven.

There are three ways to populate a layout under the status bar, the first and second of which are variations of the same principle;

1. Using new themes officially provided (Deprecated)

Using the new themes. The Holo. NoActionBar. TranslucentDecor and Theme. The Holo. Light. NoActionBar. TranslucentDecor sets the system status bar to partially transparent;

<style name="AppStyle" parent="@android:style/Theme.Holo.NoActionBar.TranslucentDecor">
	...
</style>
Copy the code

This approach is no longer recommended. After 5.0, it is recommended to use the Material theme or appCompat-related API. @deprecated Use Material themes on API 21+ or AppCompat on supported APIs

2. Use theme properties

Added in the theme style windowTranslucentNavigation and windowTranslucentStatus style properties

<style name="{Your Theme Name}">
      <item name="windowTranslucentStatus">true</item>
      <item name="windowTranslucentNavigation">true</item>
      <item name="windowContentOverlay">@null</item>
</style>
Copy the code

It is similar in nature to the first one, which simply sets the above properties when providing the theme;

3. Code method (recommended)

Use the following code can be realized transparent status bar activity. The getWindow () addFlags (WindowManager. LayoutParams. FLAG_TRANSLUCENT_STATUS);

About the WindowManager. LayoutParams. FLAG_TRANSLUCENT_STATUS introduction:

    /**
       * Window flag: request a translucent status bar with minimal system-provided
       * background protection.
       *
       * <p>This flag can be controlled in your theme through the
       * {@link android.R.attr#windowTranslucentStatus} attribute; this attribute
       * is automatically set for you in the standard translucent decor themes
       * such as
       * {@link android.R.style#Theme_Holo_NoActionBar_TranslucentDecor},
       * {@link android.R.style#Theme_Holo_Light_NoActionBar_TranslucentDecor},
       * {@link android.R.style#Theme_DeviceDefault_NoActionBar_TranslucentDecor}, and
       * {@link android.R.style#Theme_DeviceDefault_Light_NoActionBar_TranslucentDecor}.</p>
       *
       * <p>When this flag is enabled for a window, it automatically sets
       * the system UI visibility flags {@link View#SYSTEM_UI_FLAG_LAYOUT_STABLE} and
       * {@link View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}.</p>
       */
      public static final int FLAG_TRANSLUCENT_STATUS = 0x04000000;
Copy the code

All aspects of the 4.4 Transparent status bar are explained in the comments;

Pictured above,

They say there’s no picture, there’s no truth.

Due to the limited storage space of the computer, even a 4.4 simulator can not run, so I quoted pictures from other blogs, if there is infringement, please contact to delete.

Pictures from: blog.csdn.net/shanshui911…

You can see that the status bar overlays the layout;

summary

In the 4.4 status bar, you can only set the layout content to be displayed under the status bar, nothing more. There is no function to change the color of the status bar.

What? How did it end? The library provided by the wangwu family next door can set different colors of the status bar oh, the library provided by zhang Sanjia on the other side is even worse, can also set a gradient background with the status bar, or even display a flower on it, why you have nothing;

Yeah, little brother don’t panic don’t panic, as long as you like, the status bar background into animation can be, to fashion force absolutely cool; What is going on here? Listen to me slowly.

Function extension

As you can clearly see from the above renderings, the status bar overwrites the layout, but most of the time you just need to change the background color of the status bar and leave the rest as it is. So how do you implement this?

In fact, since the layout can be extended to the status bar, so we put a View at the top of the layout with the same height as the status bar, since we placed the View, then want to set what color background is not simple? The gradient background is a piece of cake, even if you want to create a Maserati Oaks aircraft XXX effect, as long as the View supports it, it is not a problem.

However, since most interfaces require the same color for the status bar, if we put a View in the layout with the same height as the status bar, it would not be exhausting, but also enjoyable. Can you still be happy to masturbate?

So encapsulation, encapsulating this layer of operations, is the strategy that most third-party libraries use. In the 4.4-5.0 DecorView (which is mostly 4.4), we add a View in the DecorView that is the height of the status bar to control the background color of the status bar

Override Fun setStatusBarColor(activity: activity, color1: Int, color2: Int, ratio: Float) {/ / transparent status bar: layout content can be extended to the activity under the status bar. The window. The addFlags (WindowManager. LayoutParams. FLAG_TRANSLUCENT_STATUS) // Find or add a simulated status bar View: To find the aim is to avoid multiple add val statusBar = findOrAddNewFakeStatusBar (activity) / / calculation shows that the color of the val blendColor = blendColor (activity, Color1, color2, thewire) / / will be simulated color as the background of the status bar view statusBar. SetBackgroundColor (blendColor) / / set the contentview fitsSystemWindows, Avoid contentView being overwritten by the status bar val rootView = (Activity.findViewById (Android.r.I.C.Tent) as ViewGroup).getChildAT (0) as ViewGroup RootView. FitsSystemWindows = true} / * * * find or add a new simulation status bar * / private fun findOrAddNewFakeStatusBar (activity: Activity): FakeStatusBar { val decorView = activity.window.decorView as ViewGroup var statusBarView: View? = decorView.findViewById(fakeStatusBarId) if (statusBarView == null || statusBarView ! is FakeStatusBar) { statusBarView = FakeStatusBar(activity).apply { id = fakeStatusBarId } decorView.addView(statusBarView) } if (statusBarView.visibility ! = View.VISIBLE) { statusBarView.visibility = View.VISIBLE } return statusBarView }Copy the code

There are many different implementations to encapsulate and process, just remember the above summary and what 4.4 provides.

Why some libraries ask you to set the status bar color after setContentView This is probably because the DecorView is a FrameLayout. If you call setContentView to add a status View of equal height, it overwrites the status View of equal height.

On the blackboard

Version 4.4 only provides support for extending layout content to display below the status bar, as explained above; So if you want to achieve a similar top picture under the status bar requirements, just need to enable this function to achieve; To control the background color of the status bar, it is achieved by placing a View under the status bar at the same height as the status bar.

5.0

Status bar processing, is nothing more than to control the status bar background color, or to extend the layout to the status bar display; In version 4.4, there was no way to set the background color of the status bar directly, and only some other way to do this. However, after version 5.0, there was official support for setting the background color of the status bar.

The method call activity. Window. StatusBarColor = color can set the background color of the status bar, but that doesn’t work, only we see statusBarColor method:

    /**
     * Sets the color of the status bar to {@code color}.
     *
     * For this to take effect,
     * the window must be drawing the system bar backgrounds with
     * {@link android.view.WindowManager.LayoutParams#FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS} and
     * {@link android.view.WindowManager.LayoutParams#FLAG_TRANSLUCENT_STATUS} must not be set.
     *
     * If {@code color} is not opaque, consider setting
     * {@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_STABLE} and
     * {@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}.
     * <p>
     * The transitionName for the view background will be "android:status:background".
     * </p>
     */
    public abstract void setStatusBarColor(@ColorInt int color);
Copy the code

As the notes clearly state, Let statsuBarColor take effect, you must set up the android. The WindowManager. LayoutParams# FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, and cannot be set android. The Wind Owmanager.layoutparams #FLAG_TRANSLUCENT_STATUS, so the complete code is as follows

Val color = XXX activity.window.apply {// Add key flag bits -- the heart of the status bar and NavigationBar color Settings AddFlags (WindowManager. LayoutParams. FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) / / must be removed this flag to set the status bar color effect ClearFlags (WindowManager. LayoutParams. FLAG_TRANSLUCENT_STATUS) / / set the status bar color statusBarColor = color}Copy the code

This is the end of the status bar functionality for 5.0; 5.0 provides support for setting the background color of the status bar to compensate for the lack of 4.4.

I still have a lot of doubts about whether the layout will extend to the status bar after I set it this way, or not. I’m a little confused, and you have no picture and no truth.

Take a closer look at the previous code, which modifies the background color of the status bar and clears itWindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUSLogo, ah, this logo is a little familiar ah, as if seen somewhere; This sign is in 4.4 increase, its role is that version 4.4 and earlier after setting this flag, layout and content will be extended to the status bar, so 5.0 sets the status bar color cleared this flag into effect to make the status bar, the background color, so that means the code above will only change the background color of the status bar, It doesn’t extend the layout below the status bar, meaning that the status bar doesn’t overwrite your layout. Let’s run the code above to see what it looks like:

So what if you want the top image to be under the status bar? Dude, LIKE I said, the blah, blah, blah sign, if we add itWindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, you can implement this function in exactly the same way as 4.4. Is it that simple? Of course, since we did not set the color of the status bar, the background of the status bar is a translucent layer, which looks like this:

Is there any way to change the background of the status bar? For example, the status bar is transparent when I look at other people’s homes. Of course, there is a way to change the color of the status bar. We can change the background color of the status bar to transparent.

But seem to conflict, set the color status bar to remove WindowManager. LayoutParams. FLAG_TRANSLUCENT_STATUS logo, sets the status bar to cover layout to add this flag, to add a function implementation, implementation can not add a function, It’s a conflict to have both functions… After setting the color and adding the flag, I found that the color of the status bar did not change, but the layout content extended under the status bar (as expected).

We look at the WindowManager. LayoutParams. FLAG_TRANSLUCENT_STATUS annotation instructions (front has provided, turn back and look at), When this flag is enabled for a window, it automatically sets the system UI visibility flags {@link View#SYSTEM_UI_FLAG_LAYOUT_STABLE} and {@link View# SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}. This means, when with Windows add WindowManager. LayoutParams. FLAG_TRANSLUCENT_STATUS after sign, View#SYSTEM_UI_FLAG_LAYOUT_STABLE and View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN will be automatically added to system UI visiblity flags. The system UI Flags are used to specify the color of the status bar and manually add the two flags to the status bar. The code is as follows:

Activity.window.apply {// Add key flag bits -- the heart of the status bar and NavigationBar color Settings AddFlags (WindowManager. LayoutParams. FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) / / must be removed this flag to set the status bar color effect ClearFlags (WindowManager. LayoutParams. FLAG_TRANSLUCENT_STATUS) / / set the status bar statusBarColor = Color. The Color TRANSPARENT} activity.window.decorView.apply { val newSysUIFlag = systemUiVisibility or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN if (systemUiVisibility ! = newSysUIFlag) { systemUiVisibility = newSysUIFlag } }Copy the code

The actual running effect is as follows:

This is the end of the 5.0 status bar.

6.0

4.4 layout content can be extended to the status bar, 5.0 you can set the status bar, background color, which brings a problem, the status bar text and icon is light color (or white), if the background color is light color of the status bar (or white), that will lead to the two can’t see clearly, this must be a bad experience. If only we could set the color of the status bar text and ICONS.

In 6.0, the view. SYSTEM_UI_FLAG_LIGHT_STATUS_BAR flag is provided and the status bar is set to a light color mode. Here is a bit difficult to understand, after adding this flag bit, the status bar text and ICONS (only system ICONS, third-party app ICONS may not support transformation) will be displayed in dark color, compatible with the status bar background color of light mode.

    /**
     * Flag for {@link #setSystemUiVisibility(int)}: Requests the status bar to draw in a mode that
     * is compatible with light status bar backgrounds.
     *
     * <p>For this to take effect, the window must request
     * {@link android.view.WindowManager.LayoutParams#FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
     *         FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS} but not
     * {@link android.view.WindowManager.LayoutParams#FLAG_TRANSLUCENT_STATUS
     *         FLAG_TRANSLUCENT_STATUS}.
     *
     * @see android.R.attr#windowLightStatusBar
     */
    public static final int SYSTEM_UI_FLAG_LIGHT_STATUS_BAR = 0x00002000;
Copy the code

Can see from the comments, the sign is to take effect, also must add android to the window. The WindowManager. LayoutParams# FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS logo, And can not add android. View. The WindowManager. LayoutParams# FLAG_TRANSLUCENT_STATUS, so if you want to use light color patterns in the status bar, specific code is as follows:

/ / / / make sure the following code from Andme library sign an effective activity. The window. The apply {addFlags (WindowManager. LayoutParams. FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)  clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) } activity.window.decorView.apply { systemUiVisibility =  systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR }Copy the code

The status bar text and icon are in dark color:

In addition, xiaomi and Meizu, among the domestic manufacturers, provided this function in some models before 6.0, but the two manufacturers also used the official method later. Therefore, considering the third-party difference and the current device share, I also think we can ignore this aspect.

So far the status bar to here to stop, what water screen, bangs screen what, then again, can only sigh, writing an article is not a little time, really is too much time.

Andme making address

Welcome to group communication: QQ276097690

More welcome to pay attention to public number

If you have more suggestions or exchanges, welcome to join the group discussion, add the public account can be the first time to understand the latest content.