There are many online articles about bangs adaptation, but there are few that can be clearly explained. Most of them are copies of documents, long speeches, and even enthusiastic stickers to tell you what bangs are. In the end, you are still not sure what kind of adaptation scheme is in order to make your app really suitable for all bangs models.

Read this article you no longer need to resent the major manufacturers following the trend of “bangs”, because the adaptation of bangs screen is very simple.

Ok, nonsense said, start adaptation.

First of all, it should be clear which interface needs to be adapted to screen bangs:

  • Interface with status bar: The fringe area displays the status bar. No adaptation is required
  • Full-screen interface: The fringe area may block the content and needs to be adapted

If you have a status bar on all screens in your app, congratulations, you don’t have to do anything, the status bar just shows up in the bangs area.

Unfortunately, there’s a good chance that your app will have a full-screen screen, and that’s exactly what bangs are for.

If you do nothing, according to the default rules do not allow the full screen interface to fringe area, namely Liu Haibing area will retain a black border, your full screen interface will display at the bottom of the bang, it looks like is also acceptable, then you have to convince the product reached an agreement, “laissez-faire” is the most powerful Liu Haibing adaptation scheme!

But some phone manufacturers (like Oppo) are not happy, I worked so hard to develop a phone with a bangs screen, you developers just give up the bangs! Then you add a message at the bottom of your full-screen screen that says “full screen”, and when the user clicks on “on”, it forces your full-screen screen into the bangs area, and all hell breaks breaks…

Well, “do nothing” doesn’t work.

Only the full-screen interface content can be displayed in the bangs area. Referring to the adaptation documents of various manufacturers, we can know how to allow this. For example, huawei models only need to configure in the AndroidManifest:

   <meta-data
       android:name="android.notch_support"
       android:value="true" />
Copy the code

After configuration, the fringe area will be displayed on the full-screen screen of Huawei models, but this fringe may block the contents of our full-screen screen. In this case, the view elements in the full screen interface should be appropriately moved down to ensure that they are not covered by bangs.

Let’s be clear: for models that allow full-screen content to be displayed in the bangs area, the view elements in the full-screen screen need to be appropriately moved down.

For example, if only huawei’s bangs are allowed to be displayed on the full-screen screen, you need to move view elements down on the full-screen screen only huawei’s bangs, but not other manufacturers’ bangs.

If the contents of huawei, Xiaomi, OPpo and Vivo full-screen screens are allowed to be displayed in the fringe area, the view elements of Huawei, Xiaomi, OPpo and Vivo fringe screens should be appropriately moved down.

You don’t have to scroll down the view elements in a full-screen screen to fit the bangs, you can also make the screen display a status bar if the product form allows.

So far bang screen adaptation finished, is not very simple! ?

Finally, the code is here for you to take:

Allows full-screen content to be displayed in the Bangs area:

<! Android :name="android.max_aspect" Android :value="2.2" /> <! <meta-data Android :name="android.notch_support" Android :value="true" /> <! <meta-data Android :name="notch. Config "Android :value="portrait" />Copy the code

The above configuration in AndroidManifest was available prior to Android 9.0, which had a new API for bangs that kept a black edge by default, meaning it was not allowed to draw to the bangs. So if you haven’t adapted Android 9.0 yet, you’ll need to add version judgment when determining if it’s a bang-screen model that allows full-screen content to be displayed in the bangs area.

Determine whether it is a bangs screen that allows full-screen content to be displayed in the bangs area:

public class CutoutUtil {

    private static Boolean sAllowDisplayToCutout;

    /** * Specifies whether the device is a bang-screen model that allows full-screen display of content in the bang-screen area (as configured in AndroidManifest) */
    public static boolean allowDisplayToCutout(a) {
        if (sAllowDisplayToCutout == null) {
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O_MR1) {
                // The 9.0 system will retain black edges by default on the full-screen interface, and do not allow content to be displayed in the bangs area
                return sAllowDisplayToCutoutDevice = false;
            }
            Context context = App.get();
            if (hasCutout_Huawei(context)) {
                return sAllowDisplayToCutout = true;
            }
            if (hasCutout_OPPO(context)) {
                return sAllowDisplayToCutout = true;
            }
            if (hasCutout_VIVO(context)) {
                return sAllowDisplayToCutout = true;
            }
            if (hasCutout_XIAOMI(context)) {
                return sAllowDisplayToCutout = true;
            }
            return sAllowDisplayToCutout = false;
        } else {
            returnsAllowDisplayToCutout; }}/** * Whether huawei Liu Screen */
    @SuppressWarnings("unchecked")
    private static boolean hasCutout_Huawei(Context context) {
        if(! Build.MANUFACTURER.equalsIgnoreCase("HUAWEI")) {
            return false;
        }
        try {
            ClassLoader cl = context.getClassLoader();
            Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
            if(HwNotchSizeUtil ! =null) {
                Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen");
                return (boolean) get.invoke(HwNotchSizeUtil);
            }
            return false;
        } catch (Exception e) {
            return false; }}/** * Whether oppo bang-screen */
    @SuppressWarnings("unchecked")
    private static boolean hasCutout_OPPO(Context context) {
        if(! Build.MANUFACTURER.equalsIgnoreCase("oppo")) {
            return false;
        }
        return context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism");
    }

    /** * Whether is vivo liu Hai screen */
    @SuppressWarnings("unchecked")
    private static boolean hasCutout_VIVO(Context context) {
        if(! Build.MANUFACTURER.equalsIgnoreCase("vivo")) {
            return false;
        }
        try {
            ClassLoader cl = context.getClassLoader();
            @SuppressLint("PrivateApi")
            Class ftFeatureUtil = cl.loadClass("android.util.FtFeature");
            if(ftFeatureUtil ! =null) {
                Method get = ftFeatureUtil.getMethod("isFeatureSupport".int.class);
                return (boolean) get.invoke(ftFeatureUtil, 0x00000020);
            }
            return false;
        } catch (Exception e) {
            return false; }}/** * Whether is xiaomi bang-screen */
    @SuppressWarnings("unchecked")
    private static boolean hasCutout_XIAOMI(Context context) {
        if(! Build.MANUFACTURER.equalsIgnoreCase("xiaomi")) {
            return false;
        }
        try {
            ClassLoader cl = context.getClassLoader();
            @SuppressLint("PrivateApi")
            Class SystemProperties = cl.loadClass("android.os.SystemProperties");
            Class[] paramTypes = new Class[2];
            paramTypes[0] = String.class;
            paramTypes[1] = int.class;
            Method getInt = SystemProperties.getMethod("getInt", paramTypes);
            / / parameters
            Object[] params = new Object[2];
            params[0] = "ro.miui.notch";
            params[1] = 0;
            return (Integer) getInt.invoke(SystemProperties, params) == 1;
        } catch (Exception e) {
            return false; }}}Copy the code

As mentioned above, it is not necessary to have the view elements in a full-screen interface be properly moved down to fit the bangs, but if the product form allows, it is possible to make the interface display a status bar.

The status bar scheme is generally simple, or, in an application, some full-screen interfaces often allow the status bar scheme to be used. If you consider using this scheme, it will look like this:

  • In your app, if you expect certain full-screen screens to be full-screen on a bang-screen model, you can move the elements down to avoid being obscured by bangs. And some of the full screen interface is not necessarily full screen display, allow in the bangs screen model display status bar, then by displaying the status bar, so as to avoid being covered by bangs.

To achieve this effect, we need to mark which screens must be displayed in full screen and which screens allow the status bar. An interface Activity that allows a status bar to be displayed inherits an interface, such as:

public interface CutoutAdapt {}Copy the code

Then in ActivityLifecycleCallbacks callback, unified adapter allows full-screen interface by displaying the status bar:

@Override
public void onActivityStarted(Activity activity) {
    // If it is a model that allows full-screen display to the bang-screen area
    if (CutoutUtil.allowDisplayToCutout()) {
        if (isFullScreen(activity)) {
            // If the status bar is allowed to be displayed, screen bangs can be adapted
            if (activity instanceof CutoutAdapt) {
                // Display the status bar
                StatusBarUtil.showStatusbar(activity.getWindow());
            } else {
                // You need to move the interface view element down by yourself, otherwise it may be obscured by bangs}}else {
            // A non-full-screen interface does not need to adapt to the fringe screen}}}Copy the code