When developing apps in React-Native, it is inevitable that the color of the status bar, background and font will match the color of the App content page. In other words, the color of the status bar will be consistent with the color of the App to make the user interface more integrated.

1. Android device system elements

  • Navigation bar: the information bar on the top of the device, such as network, time and battery
  • ActionBar: Return button and system default header area, which is not used in RN development and is customized in Navigation
  • Navigation bar: system navigation bars such as physical return, desktop return, and application selection under the device

2. Presentation of the status bar

  • Default display, always display the status bar of the mobile phone system
  • Transparent status bar, status bar background color transparent, status bar color consistent with App color, user interface more overall.
  • Hidden status bar (immersion), the status bar is completely hidden, similar to the effect of full-screen games, video players

2.1 Default Display

The default status bar style cannot be changed

2.2 Transparent Status Bar

Transparent status bar is very common. Most apps use this mode to make the status bar color consistent with the App color, making the user interface more integrated and the whole application more beautiful.

There are many ways to implement a transparent status bar:

One, use the theme of the App is configured in App/main/res/values/styles. The XML set in the theme

<resources>

    <! -- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowTranslucentStatus">true</item>// Set the status bar to take up no space //<item name="android:windowLightStatusBar">true</item>// Set the status bar font color</style>

</resources>

Copy the code

This way supports API19, that is, Android4.4 and above, which will take effect when the App starts. When the App starts, permission confirmation and system pop-ups are not affected. When the dark layer like modal pops up, the status bar text will become light color

Only set < item name = “android: windowTranslucentStatus” > true < / item > this way set transparent status bar, status bar, the default font white, There is no way to dynamically change the background color of the StatusBar through the StatusBar, making it awkward to do things that require changing the background color of the StatusBar

Add a < item name = “android: windowLightStatusBar” > true < / item > after this set font colors for each status bar on dark modal pop-up font don’t dynamic changes into a white, However, you can change the barStyle via StatusBar, which is actually not very convenient

2. Android native Settings, set in onCreate of MainActivity

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Set the transparent status bar
    if (Build.VERSION.SDK_INT >= 21) {
        View decorView = getWindow().getDecorView();
        int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
        decorView.setSystemUiVisibility(option);
        getWindow().setStatusBarColor(Color.TRANSPARENT);
    }
    
    // Set transparent status bar and transparent navigation bar
    if (Build.VERSION.SDK_INT >= 21) { View decorView = getWindow().getDecorView(); int option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; decorView.setSystemUiVisibility(option); getWindow().setNavigationBarColor(Color.TRANSPARENT); getWindow().setStatusBarColor(Color.TRANSPARENT); }}Copy the code

The transparent status bar is only supported by 5.0 or higher systems, so the following code is executed only if the system version is 5.0 or higher. Then we use SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN and SYSTEM_UI_FLAG_LAYOUT_STABLE. Note that the two flags must be used together to indicate that the main content of the application takes up space in the system status bar. That is, the status bar no longer takes up space. Finally, call the Window setStatusBarColor() method to set the status bar to a transparent color.

3. Use RN’s StatusBar to set the StatusBar in the page that the App loads for the first time

<StatusBar backgroundColor='transparent' translucent barStyle={'dark-content'} / >Copy the code

In this way, the default status bar of the system will be tried when the App is just started and when the App is started, the permission is confirmed, the system popup window, etc., and then the style set above will be changed after the App page is loaded. The advantage is that you can style the status bar dynamically.

StatusBar attributes:

  • Animated: bool Specifies whether the status bar changes should be animated. These styles are currently supported: backgroundColor, barStyle, and Hidden
  • Hidden: bool Indicates whether to hide the status bar.
  • BackgroundColor: backgroundColor of the status bar.
  • 3. Always: bool Specifies whether the status bar is always transparent. When set to true, the app draws under the status bar (” immersive “– partially obscured by the status bar). Often used with status bars with translucent backgrounds.
  • BarStyle: enum(‘default’, ‘light-content’, ‘dark-content’) Sets the color of the status bar text.

One problem with each of these approaches is that the status bar no longer takes up space, so paddingTop is the height of the status bar when you layout the page.

Pure front-end can be implemented, which is also a way to adapt to the current mainstream bangs, using StatusBar. CurrentHeight to obtain the height of the device StatusBar.

2.3 Hiding the Status bar and navigation Bar

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(option);
ActionBar actionBar = getSupportActionBar();
actionBar.hide();

Copy the code

3. Compatibility Settings in the light-colored status bar

At present, the light color status bar on the market is basically black on a white background. Android6.0 and above support this setting. MIUI V6 and above, Flyme 4.0 and above

Specific compatibility schemes are as follows:

Flyme 4.0 and above

 public static boolean FlymeSetStatusBarLightMode(Window window, boolean dark) {
    boolean result = false;
    if (window! =null) {
        try {
            WindowManager.LayoutParams lp = window.getAttributes();
            Field darkFlag = WindowManager.LayoutParams.class
                    .getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
            Field meizuFlags = WindowManager.LayoutParams.class
                    .getDeclaredField("meizuFlags");
            darkFlag.setAccessible(true);
            meizuFlags.setAccessible(true);
            int bit = darkFlag.getInt(null);
            int value = meizuFlags.getInt(lp);
            if (dark) {
                value |= bit;
            } else {
                value &= ~bit;
            }
            meizuFlags.setInt(lp, value);
            window.setAttributes(lp);
            result = true;
        } catch (Exception e) {

        }
    }
    return result;
}
Copy the code

Android6.0 and above

 public static void setAndroidNativeLightStatusBar(Activity activity, boolean dark) {
    // Status bar font icon color
    View decor = activity.getWindow().getDecorView();
    if (dark) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR // Light color status bar (font icon white)
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN //contentView full screen (placed under statusbar)| View.SYSTEM_UI_FLAG_LAYOUT_STABLE); }}else{ decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); }}Copy the code

MIUI V6 and above

public static boolean MIUISetStatusBarLightMode(Activity activity, boolean dark) {
    if(Build.VERSION.SDK_INT >= 24) {return false;
    }
    boolean result = false;
    Window window=activity.getWindow();
    if (window! =null) {
        Class clazz = window.getClass();
        try {
            int darkModeFlag = 0;
            Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
            Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
            darkModeFlag = field.getInt(layoutParams);
            Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
            if(dark){
                extraFlagField.invoke(window,darkModeFlag,darkModeFlag);// The status bar is transparent and black
            }else{
                extraFlagField.invoke(window.0, darkModeFlag);// Clear the black font
            }
            result=true;

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                Development version 7.7.13 and later use the system API, the old method is invalid but does not report errors, so both methods need to be added
                if(dark){
                    activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                }else{ activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); }}}catch (Exception e){

        }
    }
    return result;
}
    
Copy the code

Called in MainActivity’s onCreate

LightStatusBarUtil.FlymeSetStatusBarLightMode(this.getWindow(), false);
LightStatusBarUtil.MIUISetStatusBarLightMode(this.false);   
LightStatusBarUtil.setAndroidNativeLightStatusBar(this.true);
Copy the code

conclusion

To achieve transparent StatusBar, the above schemes are not fully compatible with the following versions of android 4.4. I think it is more appropriate to set transparent StatusBar + light StatusBar compatibility configuration + StatusBar to cooperate with the control