Android immersive status bar implementation

Android immersive status bar implementation

More and more apps in the app market have immersive status bar designs (as shown in the figure below). The status bar and navigation bar have the same color. Android 4.4 began to support this effect, but before 4.4, the status bar was just a black frame and could not be controlled. At the same time, the support for this effect in 4.4 and 5.0 and above versions is different. Therefore, to achieve this effect, 4.4 can be classified into one category and 5.0 and above into another category. Next, we will step by step implement the following effect in 4.4 and 5.0 and above.

Navigation bar issue

In Android, there are currently two common ways to implement the top navigation bar: one is through Toolbar, and the other is through custom View. Both methods have their own advantages and disadvantages. Toolbar is an official specification, which is more convenient for developers to use, but has poor scalability and cannot achieve some special display effects. Customization can support more display effects, but requires us to write more code. The two methods also differ in achieving status bar immersion.

Remove Title

  • The default Toolbar theme has a title. When we use the Toolbar without removing the title, the application will crash and report the following error.

Therefore, when using Toolbar, we need to add the following attribute configuration in style

  1. <item name = "windowNoTitle" > true </item>

Of course, we can also dynamically remove the title through code, but when our theme inherits from Theme.AppCompat as the parent class, the title cannot be removed through code.

Customize the Navigation Bar

When we do not set the windowNoTitle property, there is a title above the navigation bar. This is obviously contrary to our goal of achieving immersive navigation bar. Therefore, to achieve immersive navigation bar,

<item name="windowNoTitle">true</item>This configuration is essential.

Set the status bar to be transparent

After removing the title, can we achieve the above effect?

At this time, we find that the status bar is still black and not immersed, so we need to set the status bar to transparent.

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

This property can only be configured in versions 4.4 and higher, but cannot be used in earlier versions. After configuring this property, the execution effect is shown in the following figure.

Solve the problem of moving the navigation bar up

At this time, the Toolbar is moved up as a whole, causing some of its functions to move under the status bar, including the content of the navigation bar, which obviously does not meet our original requirements. How to solve this problem? We add the fitSystemWindows attribute to the Toolbar to leave a space at the top of the toolbar, so that the Toolbar content is partially out of the status bar.

  1. <android.support.v7.widget.Toolbar
  2. android:id= "@+id/toolbar"  
  3. android:fitsSystemWindows= "true"  
  4. android:layout_width= "match_parent"  
  5. android:layout_height= "wrap_content" >
  6. </android.support.v7.widget.Toolbar>

Get the effect we ultimately want

Customizing the navigation bar is similar.

fitsSystemWindows Property

The previous setting for Toolbar is the fitSystemWindows property added to Toolbar, so what happens when we add its property to the outermost layout where Toolbar is located?

  1. <RelativeLayout
  2. xmlns:android= "http://schemas.android.com/apk/res/android"  
  3. xmlns:tools= "http://schemas.android.com/tools"  
  4. android:id= "@+id/activity_toolbar"  
  5. android:layout_width= "match_parent"  
  6. android:layout_height= "match_parent"  
  7. android:fitsSystemWindows= "true"  
  8. tools:context= "com.example.netease.toolbardemo.activity.ToolbarActivity" >
  9.  
  10. <android.support.v7.widget.Toolbar
  11. android:id= "@+id/toolbar"  
  12. android:layout_width= "match_parent"  
  13. android:layout_height= "wrap_content" >
  14. </android.support.v7.widget.Toolbar>
  15.  
  16. </RelativeLayout>

After execution, you can see that the effect is the same as before when the status bar was not set to transparent.

So what is the working principle of this fitSystemWindows? Through the above experiments, it is not difficult to find that this property plays a key role in the control of the immersive status bar.

Next, we will conduct an experiment to verify the role of this property. In the layout where the Toolbar is located, add a Button at the bottom of the layout.

  1. <android.support.v7.widget.Toolbar
  2. android:id= "@+id/toolbar"  
  3. android:fitsSystemWindows= "true"  
  4. android:layout_width= "match_parent"  
  5. android:layout_height= "wrap_content" >
  6. </android.support.v7.widget.Toolbar>
  7.  
  8. <Button
  9. android:text= "Test"  
  10. android:layout_width= "match_parent"  
  11. android:layout_height= "wrap_content"  
  12. android:background= "@color/colorAccent"  
  13. android:layout_alignParentBottom= "true" />

What happens when we set this property to a button?

  1. <Button
  2. android:text= "Test"  
  3. android:fitsSystemWindows= "true"  
  4. android:layout_width= "match_parent"  
  5. android:layout_height= "wrap_content"  
  6. android:background= "@color/colorAccent"  
  7. android:layout_alignParentBottom= "true" />

By comparison, it is obvious that a padding is set on the top of the View with the fitsSystemWindows attribute set. According to the previous experiments, we know that when we set the window status bar to be transparent, the entire content view will move up by the height of the status bar. Is the size of the padding currently added to the View the same as its height?

  1. Button btn = (Button) findViewById(R.id.test_btn);
  2. Log.i( "padding" , btn.getPaddingTop()+ "" );
  3. Rect frame = new Rect();
  4. getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
  5. Log.i( "height" , frame. top + "" );

Get the padding height of the button and the height of the status bar, and we can get the following log.

Through experiments, we can conclude that the fitSystemWindows attribute will add a top padding to the set View. Therefore, when we make the navigation bar immersive, setting the transparency of the window status bar will move the view upward as a whole. With the help of the fitSystemWindows attribute, a padding with the same height as the status bar is set for the top View in the view, so that the navigation bar will not be pushed into the status bar.

When we set this property in multiple views in a view, we find that only the first view that sets this property will take effect. In the view layout, the first view from top to bottom will take effect. In the hierarchy, the last view will take effect first. Therefore, its functions can be summarized as follows:

  • Add a toppadding with the same height as the status bar to the View that sets this property
  • When this property is set for multiple Views in a view, only the top View in the layout takes effect.

5.0 and above

So far, we can achieve an immersive status bar. The above implementation is on Android 4.4. At the top of the view, there will be a black gradient shadow. The display effect on 5.0 devices is as follows. There will be a shadow on the entire status bar. Of course, different manufacturers have their own optimizations for this. For example, Meizu does not have a shadow on 4.4.

For 5.0 and above, the official provides the corresponding API for controlling the color of the status bar. We can control the color of the status bar through code to achieve the following effects.

Implementation Code

  1. if(Build.VERSION.SDK_INT >= 21) {
  2. Window window = getWindow();
  3. //Cancel the transparent status bar so that the ContentView content no longer immerses under the status bar
  4. window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  5. //You need to set this flag to call setStatusBarColor to set the status bar color
  6. window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
  7. //Set the status bar color
  8. window.setStatusBarColor(getResources().getColor(R.color.yx_red));
  9. }

From this, we can see that when we implement 5.0 and above, we do not need to set the status bar transparency and the fitSystemWindows property, and can control it directly through code. However, in order to adapt to version 4.4, it is recommended to implement it in the code as before. If you want to implement shadow removal in 5.0 and higher versions, you can control it manually in the code.

<<:  MVP Pattern in Android (with Examples)

>>:  Android application memory leak analysis and improvement experience summary

Recommend

Be careful! Be careful when you encounter this kind of ant!

Recently, Mr. Zhou from Foshan, Guangdong went on...

Double 11 is coming, how to rely on private domain traffic for marketing?

In the article shared today, we combined the cont...

How does product operations carry out product planning?

Recently I have been exploring a new business tha...

Shenzhou 14 astronauts' first spacewalk! What's different about this spacewalk?

September 1st 19:09 Astronauts Chen Dong and Liu ...

Apple: Ban Samsung from selling! Judge: If you beat me, I'll leave first

[[128651]] Apple told a U.S. appeals court on Wed...

Weibo Fantong & self-media traffic, how to make 1 million per month?

Preface | As everyone has experienced—— iPhones h...

Marketing hotspots and advertising suggestions in August!

Chinese Valentine's Day, the start of the sch...

How to formulate an operating strategy for a product?

When it comes to the work content of operations, ...