目前Android各大厂商都有Iphone X风格的刘海屏了,但是,在国内的各厂商的刘海屏适配也是个蛋疼的事,各自有各自的规则,大部分还没有升级到Android P,使开发者没办法统一使用Android API进行适配。
这里写了几个大厂的刘海屏的适配,其实也就是在各厂商的开发者平台查查都是可以找到的,现在就简单做个记录吧。
public final class NotchScreenUtil { /** * 华为start */ // 判断是否是华为刘海屏 public static boolean hasNotchInScreenAtHuawei(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); Log.d("NotchScreenUtil", "this Huawei device has notch in screen?"+ret); } catch (ClassNotFoundException e) { Log.e("NotchScreenUtil", "hasNotchInScreen ClassNotFoundException", e); } catch (NoSuchMethodException e) { Log.e("NotchScreenUtil", "hasNotchInScreen NoSuchMethodException", e); } catch (Exception e) { Log.e("NotchScreenUtil", "hasNotchInScreen Exception", e); } return ret; } /** * 获取华为刘海的高 * @param context * @return */ public 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("NotchScreenUtil", "getNotchSize ClassNotFoundException"); } catch (NoSuchMethodException e) { Log.e("NotchScreenUtil", "getNotchSize NoSuchMethodException"); } catch (Exception e) { Log.e("NotchScreenUtil", "getNotchSize Exception"); } return ret[1]; } /** * 华为end */ /** * Oppo start */ public static boolean hasNotchInScreenAtOppo(Context context) { boolean hasNotch = context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism"); Log.d("NotchScreenUtil", "this OPPO device has notch in screen?"+hasNotch); return hasNotch; } public static int getNotchSizeAtOppo() { return 80; } /** * Oppo end */ /** * vivo start */ public static final int NOTCH_IN_SCREEN_VOIO = 0x00000020;// 是否有凹槽 public static final int ROUNDED_IN_SCREEN_VOIO = 0x00000008;// 是否有圆角 public static boolean hasNotchInScreenAtVivo(Context context) { boolean ret = false; try { ClassLoader cl = context.getClassLoader(); Class<?> FtFeature = cl.loadClass("com.util.FtFeature"); Method get = FtFeature.getMethod("isFeatureSupport", int.class); ret = (Boolean) get.invoke(FtFeature, NOTCH_IN_SCREEN_VOIO); Log.d("NotchScreenUtil", "this VIVO device has notch in screen?" + ret); } catch (ClassNotFoundException e) { Log.e("NotchScreenUtil", "hasNotchInScreen ClassNotFoundException", e); } catch (NoSuchMethodException e) { Log.e("NotchScreenUtil", "hasNotchInScreen NoSuchMethodException", e); } catch (Exception e) { Log.e("NotchScreenUtil", "hasNotchInScreen Exception", e); } return ret; } public static int getNotchSizeAtVivo(Context context){ return dp2px(context, 32); } /** * vivo end */ /** * dp转px * @param context * @param dpValue * @return */ private static int dp2px(Context context, int dpValue) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue,context.getResources().getDisplayMetrics()); } /** * 获取手机厂商 * * @return 手机厂商 */ public final static int DEVICE_BRAND_OPPO = 0x0001; public final static int DEVICE_BRAND_HUAWEI = 0x0002; public final static int DEVICE_BRAND_VIVO = 0x0003; @SuppressLint("DefaultLocale") public static int getDeviceBrand() { String brand = android.os.Build.BRAND.trim().toUpperCase(); if (brand.contains("HUAWEI")) { Log.d("device brand", "HUAWEI"); return DEVICE_BRAND_HUAWEI; }else if (brand.contains("OPPO")) { Log.d("device brand", "OPPO"); return DEVICE_BRAND_OPPO; }else if (brand.contains("VIVO")) { Log.d("device brand", "VIVO"); return DEVICE_BRAND_VIVO; } return 0; } }
以上,记录了华为、Oppo、Vivo三家厂商的屏幕适配,也经过测试,用起来没什么问题。
使用的时候,可以使用getDeviceBrand()根据各厂商判断用户手机是否是刘海屏,如果是的话,则通过各厂商的方法获取刘海的高度。获取到高度了,具体的适配,就可以根据各自的需求功能具体实现。