** This is the 7th day of my participation in the August Changwen Challenge. For details, see: August Changwen Challenge **

preface

Immersion is to provide the user with a completely immersive experience, the user has a sense of being in the virtual world;

This kind of experience is widely used in all kinds of games. Most games will be opened, so that the screen is completely occupied by the game, so that players can be immersed in it, and the immersive effect will be better in terms of experience.

A lot of people on the Internet have written about the principle of immersion, and it’s not very clear, it’s very confusing;

Today we’re going to thoroughly summarize immersive implementations and principles;

** More knowledge in the public number [Android development programming] **

I. The concept of immersion and why it is used

1. Immersion concept

  • The status bar was black until 4.4, when 4.4 introduced the feature Windows TranslucentStatus, which began to introduce the concept of “immersive status bar.” In the Android 4.4 API description page, Google always mentions that “System UI Styling”, a transparent system UI style.

  • “Immersive status bar” should be “transparent bar” accurately, which is the new design specification defined in 4.4;

  • To put it simply, when the software is opened, the color of the notification bar and the top of the software are integrated, which can make the software and the system itself more consistent. At the same time, the color of the notification bar is no longer white or black.

  • Immersive means the full screen display of the phone screen is no built-in phone controls;

2. Why use immersion

  • If the App doesn’t currently have an immersive status bar, the status bar will appear as a black bar, and the black (white) bar below is very different from the App’s main interface. In this way, the visual height is sacrificed to some extent, and the interface area becomes smaller. The most important thing is the user’s vision and experience.

  • To put it bluntly, the user experience is good, the use of cool, high retention, so the leadership must let the development of immersive theme style;

Two, the principle of immersion and compatibility

From Android4.4 to now (Android 7.1), there are roughly three phases of immersion:

  • Android4.4 (API 19) – Android 5.0 (API 21) : This stage can be immersive, but it is not very well performed. FLAG_TRANSLUCENT_STATUS makes the StatusBar transparent and in full screen mode, and then immerges it by adding a View of the same size as the StatusBar and setting the background of the View to the color we want.

  • Android 5.0 or above (API 21) : With Android 5.0, an important property and method was added: Android :statusBarColor (for setStatusBarColor), which makes it easy to immerse. That said, with Android5.0, the system is truly immersive;

  • Android6.0 (API 23) and above: Android6.0 and above is implemented in the same way as Android 5.0 +, so why classify it as a separate and important phase? Since Android 6.0 (API 23), we can change the drawing mode of the status bar to show white or light black content and ICONS (except for Meizu phones, meizu has made the source code change, below 6.0 can be implemented).

Android4.4 (API 19) – Android 5.0 (API 21)

Android has added an important new property in 4.4: FLAG_TRANSLUCENT_STATUS

/ * *

* Window flag: request a translucent status bar with minimal system-provided

* background protection.

*

*

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}.

*

*

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}.

* /

public static final int FLAG_TRANSLUCENT_STATUS = 0x04000000;

Make the status bar transparent and change to full screen mode. When this property is valid, the system UI visibility flags SYSTEM_UI_FLAG_LAYOUT_STABLE and SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN are automatically set.

Make the StatusBar transparent and in full-screen mode with FLAG_TRANSLUCENT_STATUS, and then make it immersive by adding a View of the same size as the StatusBar and setting the background of the View to the color we want.

Set FLAG_TRANSLUCENT_STATUS in code as follows:

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

Alternatively, you can set the windowTranslucentStatus property in the Theme, as follows:

(2) Set a placeholder View with the same size as the StatusBar, if not set, the content View will be topped up by a height of StattusBar.

To extend the image to the status bar, simply set FLAG_TRANSLUCENT_STATUS

The code for adding a placeholder View is as follows:

/ / get decorView

ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();

int count = decorView.getChildCount();

// Check whether 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 status bar space for the status bar

ViewCompat.setFitsSystemWindows(rootView,true);

rootView.setClipToPadding(true);

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;

}

2, Android 5.0 (API 21) or later

With Android 5.0 as a milestone release, Google has added an important method, setStatusBarColor (corresponding property: Android :statusBarColor), which makes it easy to implement an immersive status bar. Here’s how:

/ * *

* 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}.

*

* The transitionName for the view background will be “android:status:background”.

*

* /

public abstract void setStatusBarColor(@ColorInt int color);

For this method to work, a Flag is required. Flag_draws_system_bar_background is required, and FLAG_TRANSLUCENT_STATUS is not allowed.

The background of the BACKGROUND of the SYSTEM BAR is supported by the BACKGROUND of the SCREEN. The background of the system BAR (status bar and navigation bar) is painted by the SCREEN of the screen. Then fill in the corresponding fields with the colors getStatusBarColor() and getNavigationBarColor().

getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

// Clear the FLAG_TRANSLUCENT_STATUS flag

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

getWindow().setStatusBarColor(getResources().getColor(android.R.color.holo_red_light));

You can also use this Theme directly in the vlues-v21 folder by adding the following Theme:

To extend the image to the status bar, just set windowTranslucentStatus, set statusBarColor to transparent, and set the DecorView properties:

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN |

View.SYSTEM_UI_FLAG_LAYOUT_STABLE);

3. Android 6.0 +

Android6.0 + is implemented in the same way as Android 5.0 +, so why classify it as a separate and important phase? Because starting with Android 6.0 (API 23), we can change the drawing mode of the status bar to show white or light black content and ICONS.

One problem with immersion on Android6.0 and above is that the Android status bar is white in color and ICONS. When the status bar is close to light in color, the content on the status bar becomes hard to read.

Android 6.0 adds a new property to solve this problem. The property is SYSTEM_UI_FLAG_LIGHT_STATUS_BAR, which allows you to set the status bar color and icon light black.

/ * *

* Flag for {@link #setSystemUiVisibility(int)}: Requests the status bar to draw in a mode that

* is compatible with light status bar backgrounds.

*

*

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;

For this attribute to take effect, you can only set flag_DRAWS_SYSTEM_BAR_BACKGROUND Flag and clean the FLAG_TRANSLUCENT_STATUS flag.

(1) The font of the status bar is white

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); // The default font is white

getWindow().setStatusBarColor(android.R.color.transparent); // Transparent background

(2) The font in the status bar is black

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LIGHT_STATUS_ BAR); // Black font

getWindow().setStatusBarColor(android.R.color.transparent); // Transparent background

3. Analysis of difficulties in immersive development

1. Summary of flag commonly used in immersion

View.SYSTEM_UI_FLAG_FULLSCREEN: The Activity is displayed in full screen, and the status bar is hidden

SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN: The Activity is displayed in full screen, but the status bar is not hidden and overwritten. The status bar is still visible.

(3). The SYSTEM_UI_FLAG_LAYOUT_STABLE

SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN and SYSTEM_UI_FLAG_LAYOUT_STABLE are used. Note that the two flags must be used together to indicate that the application body will take up space in the system status bar

View.SYSTEM_UI_FLAG_HIDE_NAVIGATION: hide the virtual button (navigation bar). Some phones use virtual buttons instead of physical ones.

View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION: Hide navigation bar effect as view. SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

⑥. Some mobile phones default full screen display, sometimes need to force not to display full screen with the following flag

Not full screen getWindow (). AddFlags (WindowManager. LayoutParams. FLAG_FORCE_NOT_FULLSCREEN);

Full screen getWindow (). ClearFlags (WindowManager. LayoutParams. FLAG_FORCE_NOT_FULLSCREEN);

2. Status bar font color ADAPTS

/ * * *

* Status bar font adaptation

* @param activity

* @param dark

* /

public static void darkMode(Activity activity, boolean dark) {

try {

if (isFlyme4Later()) {

/ / the meizu

darkModeForFlyme4(activity.getWindow(), dark);

} else if (isMIUI6Later()) {

/ / millet

darkModeForMIUI6(activity.getWindow(), dark);

} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

// Other general solutions

darkModeForM(activity.getWindow(), dark);

}

} catch (Exception e) {

}

}

/ * * *

* Status bar font adaptation

* @param activity

* @param dark

* /

public static void darkMode(Activity activity, boolean dark) {

try {

if (isFlyme4Later()) {

/ / the meizu

darkModeForFlyme4(activity.getWindow(), dark);

} else if (isMIUI6Later()) {

/ / millet

darkModeForMIUI6(activity.getWindow(), dark);

} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

// Other general solutions

darkModeForM(activity.getWindow(), dark);

}

} catch (Exception e) {

}

}

/ * *

* Determine if Flyme4 is above

* /

public static boolean isFlyme4Later() {

return Build.FINGERPRINT.contains(“Flyme_OS_4”)

|| Build.VERSION.INCREMENTAL.contains(“Flyme_OS_4”)

|| Pattern.compile(“Flyme OS [4|5]”, Pattern.CASE_INSENSITIVE).matcher(Build.DISPLAY).find();

}

/ * *

* Determine whether it is above MIUI6

* /

@SuppressLint(“PrivateApi”)

public static boolean isMIUI6Later() {

try {

Class<? > clz = Class.forName(“android.os.SystemProperties”);

Method mtd = clz.getMethod(“get”, String.class);

String val = (String) mtd.invoke(null, “ro.miui.ui.version.name”);

assert val ! = null;

val = val.replaceAll(“[vV]”, “”);

int version = Integer.parseInt(val);

return version >= 6;

} catch (Exception e) {

return false;

}

}

/ * *

* Android 6.0 sets font colors

* /

@RequiresApi(Build.VERSION_CODES.M)

private static void darkModeForM(Window window, boolean dark) {

window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

window.setStatusBarColor(Color.TRANSPARENT);

int systemUiVisibility = window.getDecorView().getSystemUiVisibility();

if (dark) {

systemUiVisibility |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;

} else {

systemUiVisibility &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;

}

window.getDecorView().setSystemUiVisibility(systemUiVisibility);

}

3. Understand and use fitsSystemWindows

  • In fulfilling the immersive status bar, we would use the android: fitsSystemWindows = “true” this attribute;

  • After setting the transparent StatusBar or NavigationBar, the activity content will extend to the corresponding area, making the area overlap. This has a huge impact on the situation that the content contains interactive controls. To solve this situation, The fitsSystemWindows property appears, we can add this property to any view, all the padding properties of the view that is set to this property will be inactivated, and the system will add paddingTop and paddingBottom to the view as appropriate. (When the transparent status bar is set, The system will add a paddingTop value equal to the height of the status bar for the view, and a paddingBottom value equal to the height of the navigation bar for the view when the transparent navigation bar is set.

  • By default, when multiple views have this property set, only the outermost view will take effect; We can also override some of the methods of the custom view to determine its own processing, and whether the child view has a chance to truncate and react to fitsSystemWindows on its own, For example, the DrawerLayout, CoordinatorLayout, and CollapsingToolbarLayout use a custom fitsSystemWindow.

  • There are two effects to achieve: the background image fills the entire screen, and the status bar and actionBar match in color.

We only need to extend the content to the status bar and the navigation bar, and then give the root layout Settings background images, if you need content does not appear in the status bar and navigation area to add * * * * android: fitsSystemWindows = “true” either

/ * *

* Gets the status bar height

* /

public static int getStatusBarHeight(Context context) {

int result = 24;

int resId = context.getResources().getIdentifier(“status_bar_height”, “dimen”, “android”);

if (resId > 0) {

result = context.getResources().getDimensionPixelSize(resId);

} else {

result = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,

result, Resources.getSystem().getDisplayMetrics());

}

return result;

}

Iv. Immersion wheel scheme

In fact, there are many mature immersive solutions on the Internet, and we do not need to encapsulate them. The main thing is to understand the knowledge points and check the problems when we encounter them

Online wheel StatusBarUtil

It has the following functions:

1. Set the status bar color

StatusBarUtil.setColor(Activity activity, int color)

Set the status bar to translucent

2, StatusBarUtil. SetTranslucent (Activity Activity, int statusBarAlpha)

Make the status bar transparent

StatusBarUtil.setTransparent(Activity activity)

3. Set the status bar color for the interface containing DrawerLayout (translucent and full transparent can also be set)

StatusBarUtil.setColorForDrawerLayout(Activity activity, DrawerLayout drawerLayout, int color)

4. Make the status bar transparent for an interface with ImageView as the header

StatusBarUtil.setTranslucentForImageView(Activity activity, int statusBarAlpha, View needOffsetView)

5. Use in fragments

6. Change the transparency value of the status bar by passing in the statusBarAlpha parameter. The default value is 112.

Conclusion:

This summary of knowledge, I hope to give some help to students who have not yet used immersion. If you’ve already used the immersive status bar, you’ll get a better idea of how the various versions work.

In fact, there are still a lot of knowledge points about immersion, this time summed up part of the students who need help