Android immersive status bar summary

1, Foreword

In fact, I'm not going to write this article. Why? Because there are too many articles about the immersive status bar, you can google dozens or hundreds of articles at a glance. Of course, some of them are well written and others make up for numbers. In front of the official account, Material Design was launched. There are readers' messages and hope for an article about immersion. Therefore, this article will sort out and summarize the implementation principles of various versions, and recommend a library that I think is very convenient for you.

2, Immersive general routine

Before introducing this convenient wheel, let's review the general routine of implementing immersive status bar. On Android, the operation of the status bar has been continuously improved, and the performance is getting better and better. On Android 4 4 below, we can display and hide the StatusBar and NavigationBar. But until Android 4 4. We can truly realize the immersive status bar. From Android 4 4 up to now (Android 7.1), immersion can be divided into three stages:

  • Android4.4 (API 19) - Android 5.0 (API 21): immersion can be realized at this stage, but the performance is not very good. The implementation method is: through FLAG_TRANSLUCENT_STATUS sets the status bar to transparent and full screen mode, and then adds a View of the same size as the status bar to set the background of the View to the color we want, so as to achieve immersion.
  • Android 5.0 (API 21) or above: when Android 5.0 is used, an important attribute and method android:statusBarColor (corresponding method is setStatusBarColor) is added. Through this method, we can easily realize immersive. That is, from Android 5 0, the system really supports immersive.
  • Android 6.0 (API 23) or above: in fact, Android 6 The implementation method above 0 is the same as Android 5.0 +, why should it be classified as a separate and important stage? This is because from Android 6.0 (API 23), we can change the drawing mode of the status bar and display white or light black content and icons (except Meizu mobile phones, Meizu has made source code changes, which can be realized below 6.0)

It's about these three stages. Next, let's take a look at how these three stages are realized.

2.1 Android4.4 (API 19) - Android 5.0 (API 21) implements immersive mode

Why can Android 4.4 achieve immersive effect? Because an important attribute is added in Android 4.4: FLAG_TRANSLUCENT_STATUS

 /**
         * 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;

Explanation: set the status bar to be transparent and change to full screen mode. The above explanation has made it clear that when this attribute of window is valid, the flag system ui visibility will be set automatically_ UI_ FLAG_ LAYOUT_ Stable and SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN .

There are two ways to implement this property:

It can be set in the code as follows:

activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

Of course, you can also set the attribute windowTranslucentStatus in theme, as follows:

android:windowTranslucentStatus

The effects are as follows:

The effect is shown in the figure above. It can be seen that the immersion effect is out, but there is also a problem. Our title bar and status bar overlap, which is equivalent to moving the height of StatusBar up the whole layout.

In order to return the title bar to its original position, we add a View with the same size as the StatusBar at the top of the title bar. The BackgroundColor of the View is the same color as the title bar. This View plays a role of occupying space. At this time, the title bar will move down the height of the StatusBar and return to the normal position.

Add the following code:

       //Get decorView under windowsphone
        ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
        int       count     = decorView.getChildCount();
        //Determine whether the statusBarView has been added
        if (count > 0 && decorView.getChildAt(count - 1) instanceof StatusBarView) {
            decorView.getChildAt(count - 1).setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
        } else {
            //Create a new view with the height and width of the status bar
            StatusBarView statusView = createStatusBarView(activity, color, statusBarAlpha);
            decorView.addView(statusView);
        }
        ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
        //rootview does not leave space for the status bar
        ViewCompat.setFitsSystemWindows(rootView,true);
        rootView.setClipToPadding(true);

The code for creating a View of the same size as the status bar is as follows:

 private static StatusBarView createStatusBarView(Activity activity, int color, int alpha) {
        // Draw a rectangle as high as the status bar
        StatusBarView statusBarView = new StatusBarView(activity);
        LinearLayout.LayoutParams params =
                new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
        statusBarView.setLayoutParams(params);
        statusBarView.setBackgroundColor(calculateStatusColor(color, alpha));
        return statusBarView;
    }

StatusBarView is an ordinary View.

After adding the above code, the effect is as follows:

Through the above, you can realize the immersive status bar on Android 4.4.

In addition, if a picture extends to the status bar, set flag directly_ TRANSLUCENT_ Status is OK, as follows:

Summary: Android 4 The routine of realizing immersive status bar on 4 is to add flag to window_ TRANSLUCENT_ Status flag, and then add a View site with the same size as status bar, so that the title bar will not overlap with status bar. When the picture extends to the status bar, you only need to set FLAG_TRANSLUCENT_STATUS is OK.

As mentioned earlier, immersive in Android 4 4 - Android5. The versions between 0 are not very good. As can be seen from the pictures posted above, there is a gradient at the top of the status bar, which will show a black shadow (the navigation bar at the bottom has the same effect). It has been repaired in Android 5.0.

2.2 implement immersive mode above Android 5.0 (API 21)

Android 5.0 is a milestone version. Since Android 5.0, Google has launched a new design specification Material Design, and native controls can achieve some cool UI effects. Since this version, Google has added an important method setStatusBarColor (corresponding attribute: android:statusBarColor). Through this method, you can easily implement the immersive status bar. The method is as follows:

 /**
     * 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);

Pay attention to the annotation of this method. If you want this method to take effect, it must be used with a Flag, and Flag must be set_ DRAWS_ SYSTEM_ BAR_ Backgroups, and Flag cannot be set_ TRANSLUCENT_ Status (only used for Android 4.4)

Let's take a look at flag_ DRAWS_ SYSTEM_ BAR_ Backgroups flag:

You can see that this flag is also added in Android 5.0. What is its function?

Explanation: flag is set_ DRAWS_ SYSTEM_ BAR_ Backgroups indicates that Window will be responsible for the background drawing of the system bar, draw the system bar with transparent background (status bar and navigation bar), and then fill the corresponding area with the colors of getStatusBarColor() and getNavigationBarColor(). This is the principle of realizing immersive navigation bar above Android 5.0.

Add the following code to implement immersive:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
//Note to clear FLAG_TRANSLUCENT_STATUS flag
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().setStatusBarColor(getResources().getColor(android.R.color.holo_red_light));

The effects are as follows:

Of course, it can also be used directly in Theme. Add the following topics under the values-v21 folder:

<style name="MDTheme" parent="Theme.Design.Light.NoActionBar">
        <item name="android:windowTranslucentStatus">false</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@android:color/holo_red_light</item>
    </style>

The effect is the same as that added in the above code, so the effect picture is not pasted here.

The picture extends to the status bar

In Android 5.0, to extend the picture to the status bar, just set windowTranslucentStatus and set statusBarColor to transparent:

<style name="ImageTranslucentTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <item name="android:windowTranslucentNavigation">true</item>
        <item name="android:windowTranslucentStatus">true</item>
        <!-- set up statusBarColor Transparent-->
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>

The effects are as follows:

The code is compatible with Android 5.0 by judging the version number Below 0 and above Android 5.0:

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            activity.getWindow().setStatusBarColor(calculateStatusColor(color, statusBarAlpha));
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
            int count = decorView.getChildCount();
            if (count > 0 && decorView.getChildAt(count - 1) instanceof StatusBarView) {
                decorView.getChildAt(count - 1).setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
            } else {
                StatusBarView statusView = createStatusBarView(activity, color, statusBarAlpha);
                decorView.addView(statusView);
            }

            ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
            rootView.setFitsSystemWindows(true);
            rootView.setClipToPadding(true);
            setRootView(activity);
}

2.3 Android 6.0 + realizes the character color and icon light black in the status bar

When using immersive, I will encounter a problem, that is, the word color and icon color of the status bar of Android system are white. When my theme color or picture is close to white or light color, the content on the status bar can't be seen clearly, This problem was solved in Android 6.0. Android 6.0 adds a new attribute SYSTEM_UI_FLAG_LIGHT_STATUS_BAR

Explanation: the Flag added for the setSystemUiVisibility(int) method requests the status bar drawing mode, which can be compatible with the status bar on a bright background. To set FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDSflag and clear the Flag at the same time_ TRANSLUCENT_ Statusflag will take effect.

Add the following code:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}

The effects are as follows:

In addition to adding in the code, you can also use attributes directly in the topic:

 <style name="MDTheme" parent="Theme.Design.Light.NoActionBar">
        <item name="android:windowTranslucentStatus">false</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@android:color/holo_red_light</item>
        <!-- Android 6.0 The character color and icon of the above status bar are light black-->
        <item name="android:windowLightStatusBar">true</item>
    </style>

Note: the theme should be placed under the values-v23 folder:

3, Wheel StatusBarUtil

Through the above introduction, in fact, the way and principle of realizing immersion in each version have been described. But maybe when you really practice the immersive status bar, you will feel unable to start. Therefore, I recommend a wheel StatusBarUtil,

Why recommend this library? Because this library has only one class StatusBarUtil, it is very convenient to use, just like a tool class. It encapsulates many static methods. Just use them directly. It's also convenient to add it yourself. Here are some scenarios:

Need to be called after setContentView().

setContentView(R.layout.main_activity);
...
StatusBarUtil.setColor(MainActivity.this, mColor);
  • 1. Set the color of the status bar
StatusBarUtil.setColor(Activity activity, int color)

  • 2. Set the translucency of the status bar
StatusBarUtil.setTranslucent(Activity activity, int statusBarAlpha)

  • 3. Set the status bar to be fully transparent
StatusBarUtil.setTransparent(Activity activity)

  • 4. Set the color of the status bar for the interface containing DrawerLayout (translucent and fully transparent can also be set)
StatusBarUtil.setColorForDrawerLayout(Activity activity, DrawerLayout drawerLayout, int color)

  • 5. Set the transparency of the status bar for the interface using ImageView as the Header (the common scene is the Header part of the details page)
StatusBarUtil.setTranslucentForImageView(Activity activity, int statusBarAlpha, View needOffsetView)

  • 6. Use in Fragment

status\_uti

4, Finally

The above is a summary of the immersive status bar. I hope it can give some help to students who have not yet used the immersive status bar. If you have used the immersive status bar, you can have a deeper understanding of the principle of each version. Finally, I recommend a good library, more specifically, it should be a good tool class. If you have any questions, welcome to communicate.

This article is transferred from https://juejin.cn/post/6844903490402123789 , if there is infringement, please contact to delete.

Keywords: an-d-ro-id

Added by enemeth on Tue, 25 Jan 2022 13:57:53 +0200