当前位置: 首页 > 科技观察

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

时间:2023-03-18 01:11:38 科技观察

不用再吐槽“刘海屏”了,因为适配很简单刘海屏是什么,到现在你还不确定什么样的适配方案,才能让你的app真正适配所有刘海屏机型。看完这篇文章,你就不用再反感各大厂商的“刘海”了,因为刘海的适配很简单。ok,废话说完,我们开始适应吧。首先要明确哪些界面需要适配刘海屏:有状态栏的界面:刘海区域会显示状态栏,不需要适配全面屏界面:刘海区域可能会挡住内容,需要适配如果你的应用中所有界面都有状态栏,那么恭喜你,你不用做任何操作,状态栏显示在刘海区域就这么自然,没有违和,刘海屏已经适配了,你可以点击出去。不幸的是,你的应用很有可能会出现全屏界面,而所谓的刘海适配正是针对这些全屏界面。如果你什么都不做,默认规则是不允许全屏界面的内容显示在刘海区域,即刘海区域会保留一个黑边,你的全屏界面会显示在下方刘海,看似可以接受,然后你我居然说服产品达成共识,“无为而治”才是最大的刘海适配方案!但一些手机厂商(比如oppo)并不高兴。辛辛苦苦开发出来的刘海手机,你们这些开发者居然直接放弃了刘海区域!然后你在全屏界面的底部添加了一个提示:“全屏显示”。当用户点击打开的时候,你的全屏界面就强行显示在刘海区,然后就乱七八糟了……嗯~“无为而治”行不通了。我们只能让全屏界面的内容显示在刘海区域。参考各大厂商的适配文档就知道怎么允许了。比如华为机型,只需要在AndroidManifest中配置:配置之后,华为机型上的全屏界面会显示刘海区域,但是这个刘海可能会挡住我们全屏界面的内容。这时候需要将全屏界面中的视图元素适当下移,保证不会被刘海挡住,就可以了。这里明确一下,只有让全屏内容显示在刘海区域的机型,全屏界面的视图元素才需要适当下移。比如刘海区域只允许显示华为机型全面屏界面的内容,那么只有华为刘海机型需要将全面屏界面的视图元素适当下移,而其他厂商的缺口模型不需要向下移动。如果允许华为、小米、oppo、vivo全面屏界面内容显示在刘海区域,那么华为、小米、oppo、vivo刘海屏机型需要将全面屏界面中的view元素适当下移.此外,无需通过将全屏界面中的视图元素下移来调整刘海。如果产品形态允许,还可以让界面显示状态栏。至此,刘海适配就完成了,是不是很简单!?***代码来了,感谢带走:1.允许在刘海区域显示全屏界面的内容配置:以上AndroidManifest中的配置在Android9.0之前有效。9.0系统为刘海屏开发了新的api,默认保留黑色边框,即不允许绘制到刘海区域。所以如果你还没有适配Android9.0,那么在判断是否为刘海机型允许刘海区域显示全屏界面内容时,需要添加版本判断。2、判断刘海区域是否为允许全屏界面内容显示的刘海机型:publicclassCutoutUtil{privatestaticBooleansAllowDisplayToCutout;/***是否为刘海机型允许全屏界面内容在刘海区域显示缺口区域(对应AndroidManifest中的配置)*/publicstaticbooleanallowDisplayToCutout(){if(sAllowDisplayToCutout==null){if(Build.VERSION.SDK_INT>Build.VERSION_CODES.O_MR1){//全屏界面的9.0系统默认会保留黑边,刘海区域不允许显示内容(context)){returnsAllowDisplayToCutout=true;}if(hasCutout_VIVO(context)){returnsAllowDisplayToCutout=true;}if(hasCutout_XIAOMI(context)){returnsAllowDisplayToCutout=true;}returnsAllowDisplayToCutout=false;}else{returnsAllowDisplayToCutout;}}/***是否是华为刘海屏模型*/@SuppressWarnings("unchecked")privatestaticbooleanhasCutout_Huawei(Contextcontext){if(!Build.MANUFACTURER.equalsIgnoreCase("HUAWEI")){returnfalse;}try{ClassLoadercl=context.getClassLoader();ClassHwNotchSizeUtil=cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");if(HwNotchSizeUtil!=null){Methodget=HwNotchSizeUtil.getMethod("hasNotchInScreen");return(boolean)get.invoke(HwNotchSizeUtil);}returnfalse;}catch(Exceptione){returnfalse;}}/***是否是oppo刘海屏机型*/@SuppressWarnings("unchecked")privatestaticbooleanhasCutout_OPPO(Contextcontext){if(!Build.MANUFACTURER.equalsIgnoreCase("oppo")){returnfalse;}returncontext.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism");}/***是否是vivo刘海屏机型*/@SuppressWarnings("unchecked")privatestaticbooleanhasCutout_VIVO(Contextcontext){if(!Build.MANUFACTURER.equalsIgnoreCase("vivo")){returnfalse;}try{ClassLoadercl=context.getClassLoader();@SuppressLint("PrivateApi")ClassftFeatureUtil=cl.loadClass("android.util.FtFeature");if(ftFeatureUtil!=null){Methodget=ftFeatureUtil.getMethod("isFeatureSupport",int.class);return(boolean)get.invoke(ftFeatureUtil,0x00000020);}returnfalse;}catch(Exceptione){returnfalse;}}/***是否是小米刘海屏模型*/@SuppressWarnings("unchecked")privatestaticbooleanhasCutout_XIAOMI(Contextcontext){if(!Build.MANUFACTURER.equalsIgnoreCase("xiaomi")){returnfalse;}try{ClassLoadercl=context.getClassLoader();@SuppressLint("PrivateApi")ClassSystemProperties=cl.loadClass("android.os.SystemProperties");Class[]paramTypes=newClass[2];paramTypes[0]=String.class;paramTypes[1]=int.class;MethodgetInt=SystemProperties.getMethod("getInt",paramTypes);//参数Object[]params=newObject[2];params[0]="ro.miui.notch";params[1]=0;return(Integer)getInt.invoke(SystemProperties,params)==1;}catch(Exceptione){returnfalse;}}}上面提到,不需要移动全屏界面中的视图元素来适应刘海屏。如果产品形式允许,界面还可以显示状态栏显示状态栏的方案比较笼统和简单。也就是说,在一个应用中,往往允许一些全屏界面使用显示状态栏的方案。如果你考虑使用这个方案,会是这样效果:在你的应用中,你期望一些全屏界面必须在刘海屏机型上全屏显示,那么你应该将界面元素适当下移,避免被挡住按等级;而部分全面屏界面不必全屏显示,让状态栏显示在刘海屏机型上,再显示状态栏,避免被刘海挡住。为了实现这个效果,我们需要标记哪些界面必须全屏显示,哪些界面允许显示状态栏。这里有一个实现方法,让允许显示状态栏的界面Activity继承一个接口,如:publicinterfaceCutoutAdapt{}然后在ActivityLifecycleCallbacks中回调,统一适配允许显示状态栏的全屏界面:@OverridepublicvoidonActivityStarted(Activityactivity){//如果是刘海模型,允许全屏显示到刘海区域if(CutoutUtil.allowDisplayToCutout()){if(isFullScreen(activity)){//如果允许适配刘海通过显示状态栏if(activityinstanceofCutoutAdapt){//显示状态栏StatusBarUtil.showStatusbar(activity.getWindow());}else{//需要自己将界面视图元素下移,否则可能会被遮挡thenotch}}else{//非全屏界面不需要适配notch}}}【编辑推荐】一大波刘海屏即将发布是缺乏创新还是未来主流?AndroidP六大亮点:室内定位,支持“刘海屏”危险!一样的刘海……安卓刘海一大波来袭,全网最全的适配技巧!AndroidP状态栏改成只显示4个通知图标:给刘海屏让路