Android 劉海屏 適配

Android 劉海屏 適配主要有三種方案android

第一,LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT 模式

在該模式下,若是當前應用沒有設置頁面全屏顯示,則顯示邏輯,與正常狀況同樣api

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notch);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            Window window = getWindow();
            WindowManager.LayoutParams params = window.getAttributes();
            params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
            window.setAttributes(params);
        }
    }
複製代碼

5.png

若是當前應用已設置頁面全屏顯示,則整個內容區域下移,下移高度爲 劉海的高度bash

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        Window window = getWindow();
        window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_notch);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            WindowManager.LayoutParams params = window.getAttributes();
            params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
            window.setAttributes(params);
        }
    }
複製代碼

2.png

第二,LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER模式

在該模式下,內容不會延伸到劉海區ide

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_notch);
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            Window window = getWindow();
            WindowManager.LayoutParams params = window.getAttributes();
            params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
            window.setAttributes(params);
        }
    }
複製代碼

4.png

第三,LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES模式

在該模式下,容許內容延伸進劉海區佈局

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_notch);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            Window window = getWindow();
            WindowManager.LayoutParams params = window.getAttributes();
            params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
            window.setAttributes(params);
        }
    }
複製代碼

5.png

圖中頂部爲默認狀態欄的顏色,這時候須要將頁面設置沉浸式,從而讓用戶內容充滿屏幕ui

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_notch);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            Window window = getWindow();
            WindowManager.LayoutParams params = window.getAttributes();
            params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
            window.setAttributes(params);
        }

        ImmersionUtil.setImmersive(this);
    }
複製代碼
/**
     * 設置Activit沉浸式
     */
    public static void setImmersive(Activity activity) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT || activity == null) {
            //Android4.4 之前不支持 沉浸式
            return;
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = activity.getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

            //設置狀態欄顏色透明
            window.setStatusBarColor(Color.TRANSPARENT);

            int visibility = window.getDecorView().getSystemUiVisibility();
            //佈局內容全屏展現
            visibility |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
            //隱藏虛擬導航欄
            visibility |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
            //防止內容區域大小發生變化
            visibility |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE;

            window.getDecorView().setSystemUiVisibility(visibility);

        } else {
            //Android 5.0之前
            Window window = activity.getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
    }
複製代碼

6.png

在具體頁面顯示上,須要動態獲取劉海屏的高度進行設置,通常狀況下,劉海的高度 就是狀態欄的高度this

/**
     * 獲取狀態欄高度
     */
    public static int getStatusBarHeight(Context context) {
        int resId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resId > 0) {
            return context.getResources().getDimensionPixelSize(resId);
        }
        return 0;
    }
複製代碼

可是在華爲手機上,華爲官方文檔提供了獲取劉海高度的方法spa

/**
     * 獲取華爲劉海尺寸:width、height,int[0]值爲劉海寬度 int[1]值爲劉海高度。
     */
    @SuppressWarnings("unchecked")
    private static int[] getNotchSizeAtHuaWei(Context context) {
        int[] ret = new int[]{0, 0};
        try {
            ClassLoader cl = context.getClassLoader();
            Class hwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
            Method get = hwNotchSizeUtil.getMethod("getNotchSize");
            ret = (int[]) get.invoke(hwNotchSizeUtil);

        } catch (ClassNotFoundException e) {
            Log.e("test", "getNotchSize ClassNotFoundException");
        } catch (NoSuchMethodException e) {
            Log.e("test", "getNotchSize NoSuchMethodException");
        } catch (Exception e) {
            Log.e("test", "getNotchSize Exception");
        }
        return ret;
    }
複製代碼

7.png

注:Android 劉海屏 適配使用的是 Andorid 9.0後,谷歌官方提供的api,不排除 國內個別廠商 沒有遵循 谷歌規範,從而致使 適配失敗的狀況。 (附上:個別廠商開發文檔地址)3d

相關文章
相關標籤/搜索