加入收藏 | 设为首页 | 会员中心 | 我要投稿 河北网 (https://www.hebeiwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 业界 > 正文

无需再怨恨“刘海屏”了,因为适配十分简单

发布时间:2019-03-27 19:09:36 所属栏目:业界 来源:王英豪
导读:网上关于刘海屏适配的文章不少,可讲清晰的却没几篇,大多是拷贝文档、长篇大论,乃至热情的贴图汇报你什么是刘海屏,到最后你仍不确定到底是奈何的一个适配方案,才气让你的 app 真正的适配全部的刘海屏机型。 看到这篇文章你就无需再憎恨各大厂商的跟风
副问题[/!--empirenews.page--]

网上关于刘海屏适配的文章不少,可讲清晰的却没几篇,大多是拷贝文档、长篇大论,乃至热情的贴图汇报你什么是刘海屏,到最后你仍不确定到底是奈何的一个适配方案,才气让你的 app 真正的适配全部的刘海屏机型。

无需再憎恨“刘海屏”了,由于适配异常简朴

看到这篇文章你就无需再憎恨各大厂商的跟风“刘海”了,由于刘海屏的适配异常简朴。

ok,空话说完了,开始适配。

起主要清晰的是哪些界面必要适配刘海屏:

  • 有状态栏的界面:刘海地区会表现状态栏,无需适配
  • 全屏界面:刘海地区也许遮挡内容,必要适配

假如你的应用里全部界面都有状态栏,那么恭喜你,你不消做任何操纵,状态栏就那么天然的表现在刘海地区,毫无违和,刘海屏已适配完毕,可以点叉出去了。

不幸的是,你的应用中很大几率会有全屏界面,所谓的刘海屏适配,也正是针对这些全屏界面。

假如你什么都不做,默认法则不应承全屏界面内容表现到刘海地区,即刘海屏地区会保存一条黑边,你的全屏界面会在刘海下方展示,这看起来仿佛也是可以接管的,然后你竟说服产物告竣共鸣,“无为而治”步崆最强盛的刘海屏适配方案!

但有些手机厂商(譬如oppo)不开心了,我辛辛勤苦研发的刘海屏手机,你们这些开拓者竟直接放弃刘海地区!然后就在你的全屏界面下方加了一条提醒:“全屏表现”,当用户点击开启后,强行把你的全屏界面表现到刘海地区,然后统统都乱套了...

嗯~ “无为而治”行不通。

只能应承全屏界面内容表现到刘海地区了,参考各大厂商的适配文档,我们可以知道怎样应承,好比华为机型只需在 AndroidManifest 中设置:

设置后,,华为机型上的全屏界面就会表现到刘海地区了,但这个刘海,是也许盖住我们全屏界面中的内容的。这时必要将全屏界面中的视图元素恰当下移,担保不会被刘海隐瞒住,就 ok 了。

这里我们搞清晰:应承全屏界面内容表现到刘海地区的机型,才必要将全屏界面中的视图元素恰当下移。

好比若只应承华为机型全屏界面内容表现到刘海地区,那只有华为的刘海屏机型才必要将全屏界面中的视图元素恰当下移,其他厂商的刘海屏机型则不必要下移。

假如应承华为、小米、oppo、vivo 全屏界面内容表现到刘海地区,那么华为、小米、oppo、vivo 刘海屏机型必要将全屏界面中的视图元素恰当下移。

其它也不必然要通过全屏界面中的视图元素恰当下移方法来适配刘海屏,假如产物形态应承的话,你也可以让该界面表现状态栏啊。

至此刘海屏适配完毕,是不是很简朴!?

最儿女码送上,拿走不谢:

1、应承全屏界面内容表现到刘海地区设置:

  1. <!--应承绘制到oppo、vivo刘海屏机型的刘海地区 --> 
  2. <meta-data 
  3.     android:name="android.max_aspect" 
  4.     android:value="2.2" /> 
  5.  
  6. <!-- 应承绘制到华为刘海屏机型的刘海地区 --> 
  7. <meta-data 
  8.     android:name="android.notch_support" 
  9.     android:value="true" /> 
  10.  
  11. <!-- 应承绘制到小米刘海屏机型的刘海地区 --> 
  12. <meta-data 
  13.     android:name="notch.config" 
  14.     android:value="portrait" /> 

上面在 AndroidManifest 的设置在 Android 9.0 之前有用,9.0 体系针对刘海屏拟定了新的 api,默认保存一条黑边,即不应承绘制到刘海地区。以是假如你还没有适配 Android 9.0,那在判定是否是应承全屏界面内容表现到刘海地区的刘海屏机型时,就要加上版本判定。

2、判定是否是应承全屏界面内容表现到刘海地区的刘海屏机型:

  1. public class CutoutUtil { 
  2.  
  3.     private static Boolean sAllowDisplayToCutout; 
  4.  
  5.     /** 
  6.      * 是否为应承全屏界面表现内容到刘海地区的刘海屏机型(与AndroidManifest中设置对应) 
  7.      */ 
  8.     public static boolean allowDisplayToCutout() { 
  9.         if (sAllowDisplayToCutout == null) { 
  10.             if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O_MR1) { 
  11.                 // 9.0体系全屏界面默认会保存黑边,不应承表现内容到刘海地区 
  12.                 return sAllowDisplayToCutoutDevice = false; 
  13.             } 
  14.             Context context = App.get(); 
  15.             if (hasCutout_Huawei(context)) { 
  16.                 return sAllowDisplayToCutout = true; 
  17.             } 
  18.             if (hasCutout_OPPO(context)) { 
  19.                 return sAllowDisplayToCutout = true; 
  20.             } 
  21.             if (hasCutout_VIVO(context)) { 
  22.                 return sAllowDisplayToCutout = true; 
  23.             } 
  24.             if (hasCutout_XIAOMI(context)) { 
  25.                 return sAllowDisplayToCutout = true; 
  26.             } 
  27.             return sAllowDisplayToCutout = false; 
  28.         } else { 
  29.             return sAllowDisplayToCutout; 
  30.         } 
  31.     } 
  32.  
  33.  
  34.     /** 
  35.      * 是否是华为刘海屏机型 
  36.      */ 
  37.     @SuppressWarnings("unchecked") 
  38.     private static boolean hasCutout_Huawei(Context context) { 
  39.         if (!Build.MANUFACTURER.equalsIgnoreCase("HUAWEI")) { 
  40.             return false; 
  41.         } 
  42.         try { 
  43.             ClassLoader cl = context.getClassLoader(); 
  44.             Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil"); 
  45.             if (HwNotchSizeUtil != null) { 
  46.                 Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen"); 
  47.                 return (boolean) get.invoke(HwNotchSizeUtil); 
  48.             } 
  49.             return false; 
  50.         } catch (Exception e) { 
  51.             return false; 
  52.         } 
  53.     } 
  54.  
  55.     /** 
  56.      * 是否是oppo刘海屏机型 
  57.      */ 
  58.     @SuppressWarnings("unchecked") 
  59.     private static boolean hasCutout_OPPO(Context context) { 
  60.         if (!Build.MANUFACTURER.equalsIgnoreCase("oppo")) { 
  61.             return false; 
  62.         } 
  63.         return context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism"); 
  64.     } 
  65.  
  66.     /** 
  67.      * 是否是vivo刘海屏机型 
  68.      */ 
  69.     @SuppressWarnings("unchecked") 
  70.     private static boolean hasCutout_VIVO(Context context) { 
  71.         if (!Build.MANUFACTURER.equalsIgnoreCase("vivo")) { 
  72.             return false; 
  73.         } 
  74.         try { 
  75.             ClassLoader cl = context.getClassLoader(); 
  76.             @SuppressLint("PrivateApi") 
  77.             Class ftFeatureUtil = cl.loadClass("android.util.FtFeature"); 
  78.             if (ftFeatureUtil != null) { 
  79.                 Method get = ftFeatureUtil.getMethod("isFeatureSupport", int.class); 
  80.                 return (boolean) get.invoke(ftFeatureUtil, 0x00000020); 
  81.             } 
  82.             return false; 
  83.         } catch (Exception e) { 
  84.             return false; 
  85.         } 
  86.     } 
  87.  
  88.     /** 
  89.      * 是否是小米刘海屏机型 
  90.      */ 
  91.     @SuppressWarnings("unchecked") 
  92.     private static boolean hasCutout_XIAOMI(Context context) { 
  93.         if (!Build.MANUFACTURER.equalsIgnoreCase("xiaomi")) { 
  94.             return false; 
  95.         } 
  96.         try { 
  97.             ClassLoader cl = context.getClassLoader(); 
  98.             @SuppressLint("PrivateApi") 
  99.             Class SystemProperties = cl.loadClass("android.os.SystemProperties"); 
  100.             Class[] paramTypes = new Class[2]; 
  101.             paramTypes[0] = String.class; 
  102.             paramTypes[1] = int.class; 
  103.             Method getInt = SystemProperties.getMethod("getInt", paramTypes); 
  104.             //参数 
  105.             Object[] params = new Object[2]; 
  106.             params[0] = "ro.miui.notch"; 
  107.             params[1] = 0; 
  108.             return (Integer) getInt.invoke(SystemProperties, params) == 1; 
  109.         } catch (Exception e) { 
  110.             return false; 
  111.         } 
  112.     } 
  113.  

上面提到,不必然要通过全屏界面中的视图元素恰当下移方法来适配刘海屏,假如产物形态应承的话,也可以让该界面表现状态栏。

表现状态栏的方案是较为通用简朴的,可能说,在一个应用中,一些全屏界面每每是应承行使表现状态栏的方案来适配的,假如你思量行使这种方案,那便会是这种结果:

(编辑:河北网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读