您好,登錄后才能下訂單哦!
Android8.0以后【凹口屏】得到迅速發展,目前已有了挖孔屏/水滴屏/劉海屏等各式各樣的屏幕,究其根本依舊是【凹口屏】,單華為一個品牌就涵蓋了基本所有類型,而對于屏幕適配也是不可逃避的問題。小菜單獨對華為各型號屏幕進行適配嘗試,部分方法可通用到其他品牌設備,為 Android 標準 SDK 方法。
其實凹口屏已經出現很久了,對于獲取凹口寬高的方式也有很多種,但是以前主流的凹口屏中凹口位置一般是位于屏幕正上方,但隨著發展,也出現了在左上角的挖孔屏樣式。相應的, Android 9.0 即 SDK28 也發布了獲取凹口屏的方法。
Android 9.0 以下適配方案
對華為設備凹口屏適配情況來說,若僅需獲取凹口位置的寬高,如下方法即可,在 Android 各版本中均可( Android 9.0 及以上亦可)。此時獲取屏幕水平方向安全位置時,可根據屏幕寬度-凹口寬度再左右均分即可。
/** * 華為凹口屏判斷方法 Android 各版本均可 * @param context * @return */ public static boolean hasNotchInScreen(Context context) { boolean ret = false; try { ClassLoader cl = context.getClassLoader(); Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil"); Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen"); ret = (boolean) get.invoke(HwNotchSizeUtil); } catch (ClassNotFoundException e) { Log.e(TAG, "hasNotchInScreen ClassNotFoundException"); } catch (NoSuchMethodException e) { Log.e(TAG, "hasNotchInScreen NoSuchMethodException"); } catch (Exception e) { Log.e(TAG, "hasNotchInScreen Exception"); } finally { return ret; } } /** * 華為凹口屏寬高獲取方式 int[]{width, height} * @param context * @return */ public static int[] getNotchSize(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(TAG, "getNotchSize ClassNotFoundException"); } catch (NoSuchMethodException e) { Log.e(TAG, "getNotchSize NoSuchMethodException"); } catch (Exception e) { Log.e(TAG, "getNotchSize Exception"); } finally { notchWidth = ret[0]; notchHeight = ret[1]; return ret; } }
Android 9.0 及以上適配
對于華為新出的挖孔屏設備基本均為 Android 9.0 及以上, Android 9.0 提供了對凹口屏相關的 SDK ,谷歌認為凹口位置可以不固定位置也不固定個數,但是對于設備一條邊只能有一個;如下方法對于 Android 9.0 及以上設備判斷均可。 SDK 不僅可以判斷是否為凹口屏,同時可以獲取各個凹口大小及所在位置。
步驟如下: 升級 build.gradle 中 compileSdkVersion 或 targetSdkVersion 為 28 ; 在 Application 或 Activity 中設置 meta-data 屬性,小菜測試不設置亦可;
<meta-data android:name="android.notch_support" android:value="true"/>
根據如下方法獲取相應參數;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { getSupportActionBar().hide(); getWindow().getDecorView() .setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); //設置頁面全屏顯示 WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; //設置頁面延伸到凹口區顯示 getWindow().setAttributes(lp); getWindow().getDecorView() .findViewById(android.R.id.content) .getRootView() .setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { @Override public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) { DisplayCutout cutout = windowInsets.getDisplayCutout(); if (cutout == null) { Log.e(TAG, "cutout==null, is not notch screen");//通過cutout是否為null判斷是否凹口手機 isNotchScreen = false; } else { List<Rect> rects = cutout.getBoundingRects(); if (rects == null || rects.size() == 0) { Log.e(TAG, "rects==null || rects.size()==0, is not notch screen"); isNotchScreen = true; } else { Log.e(TAG, "rect size:" + rects.size());//注意:凹口的數量可以是多個 isNotchScreen = true; for (Rect rect : rects) { notchRight = rect.right; notchLeft = rect.left; notchTop = rect.top; notchBottom = rect.bottom; notchWidth = notchRight - notchLeft; notchHeight = notchBottom - notchLeft; safeLeft = cutout.getSafeInsetLeft(); safeRight = cutout.getSafeInsetRight(); safeTop = cutout.getSafeInsetTop(); safeBottom = cutout.getSafeInsetBottom(); } } } return windowInsets; } }); }
注意事項: 小菜在設置 Application 或 Activity 的主題為 NoActionBar 樣式,此時要去掉 getSupportActionBar().hide(); 否則會報空指針異常;
<style name="NoBarTheme" parent="Theme.AppCompat.NoActionBar"> <item name="android:windowNoTitle">true</item> <item name="android:windowContentOverlay">@null</item> </style>
如下設置全屏使用凹口屏時要注意 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN ,否則參數很有可能獲取不到;
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; getWindow().setAttributes(lp);
設置主題 NoActionBar 或代碼中動態設置 getSupportActionBar().hide(); 展示效果在 Android 9.0 以下有部分差異,如下:
NoActionBar 主題
AppTheme 主題
對于凹口屏適配還有很多機型要單獨處理,以上僅對華為設備進行參考;如果有不對的地方還希望多多指出。也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。