成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

無需再怨恨“劉海屏”了,因為適配十分簡單

移動開發
網上關于劉海屏適配的文章不少,可講清楚的卻沒幾篇,大多是拷貝文檔、長篇大論,甚至熱情的貼圖告訴你什么是劉海屏,到最后你仍不確定到底是怎樣的一個適配方案,才能讓你的 app 真正的適配所有的劉海屏機型。

網上關于劉海屏適配的文章不少,可講清楚的卻沒幾篇,大多是拷貝文檔、長篇大論,甚至熱情的貼圖告訴你什么是劉海屏,到***你仍不確定到底是怎樣的一個適配方案,才能讓你的 app 真正的適配所有的劉海屏機型。

[[260668]]

看到這篇文章你就無需再怨恨各大廠商的跟風“劉海”了,因為劉海屏的適配十分簡單。

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.  

上面提到,不一定要通過全屏界面中的視圖元素適當下移方式來適配劉海屏,如果產品形態允許的話,也可以讓該界面顯示狀態欄。

顯示狀態欄的方案是較為通用簡單的,或者說,在一個應用中,一些全屏界面往往是允許使用顯示狀態欄的方案來適配的,如果你考慮使用這種方案,那便會是這種效果:

在你的應用中,你期望某些全屏界面在劉海屏機型上必須全屏展示,那你就自行將界面元素適當下移,從而避免被劉海遮擋;而某些全屏界面不是非要全屏顯示,允許在劉海屏機型顯示狀態欄,那就通過顯示狀態欄的方式,從而避免被劉海遮擋。

為了實現這種效果,我們需要標記區分哪些界面必須全屏展示、哪些界面允許顯示狀態欄。這里提供一種實現方式,讓允許顯示狀態欄的界面 Activity 繼承一個接口,比如:

  1. public interface CutoutAdapt { 

然后在 ActivityLifecycleCallbacks 回調,統一適配允許通過顯示狀態欄的全屏界面:

  1. @Override 
  2. public void onActivityStarted(Activity activity) { 
  3.     // 如果是允許全屏顯示到劉海屏區域的劉海屏機型 
  4.     if (CutoutUtil.allowDisplayToCutout()) { 
  5.         if (isFullScreen(activity)) { 
  6.             // 如果允許通過顯示狀態欄方式適配劉海屏 
  7.             if (activity instanceof CutoutAdapt) { 
  8.                 // 顯示狀態欄 
  9.                 StatusBarUtil.showStatusbar(activity.getWindow()); 
  10.             } else { 
  11.                 // 需自行將該界面視圖元素下移,否則可能會被劉海遮擋 
  12.             } 
  13.         } else { 
  14.             // 非全屏界面無需適配劉海屏 
  15.         } 
  16.     } 

 【編輯推薦】

責任編輯:未麗燕 來源: 簡書
相關推薦

2010-01-04 15:39:24

Ubuntu SVN

2010-02-05 14:57:31

Ubuntu SVN

2021-06-08 05:53:31

H5 頁面項目劉海屏適配

2020-12-17 06:48:21

SQLkafkaMySQL

2018-04-12 14:56:49

Android劉海屏技巧

2019-04-01 14:59:56

負載均衡服務器網絡

2022-06-16 07:31:41

Web組件封裝HTML 標簽

2024-06-19 09:58:29

2021-09-07 09:40:20

Spark大數據引擎

2015-10-28 13:57:29

融合架構華三UIS

2023-04-12 11:18:51

甘特圖前端

2009-09-25 08:38:25

Hibernate數據

2015-09-06 09:22:24

框架搭建快速高效app

2012-07-10 01:22:32

PythonPython教程

2023-11-30 10:21:48

虛擬列表虛擬列表工具庫

2024-05-13 09:28:43

Flink SQL大數據

2020-12-18 11:46:25

人工智能人工智能技術

2013-11-18 13:46:56

2019-09-16 09:14:51

2009-10-09 14:45:29

VB程序
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美午夜视频 | 韩国欧洲一级毛片 | 中文字幕二区三区 | 国产精品国产a级 | 亚洲精品一区二 | 亚洲三级免费看 | 国产大学生情侣呻吟视频 | 国产乱码精品一区二区三区忘忧草 | 91不卡 | 国产高潮好爽受不了了夜色 | 伊伊综合网 | 国产ts人妖一区二区三区 | 精品久久久久久红码专区 | 久草视频网站 | 国产精品jizz在线观看老狼 | 欧美日产国产成人免费图片 | 国产a区 | 国产高清一区二区 | 涩涩视频网站在线观看 | 一级免费毛片 | 成人亚洲视频 | 伊人亚洲| 国产情品| 午夜看电影在线观看 | 国产性网| 久久久久国产精品一区二区 | 日本精品视频一区二区三区四区 | 蜜桃传媒一区二区 | 精品一区二区三区中文字幕 | 欧美激情综合五月色丁香小说 | 欧美精品二区 | 最新国产精品精品视频 | 久久成人精品一区二区三区 | 国产欧美精品区一区二区三区 | julia中文字幕久久一区二区 | 久久伊人操 | 中文字幕亚洲一区二区三区 | 天天插天天舔 | 精品欧美一区二区三区久久久 | 在线观看日本网站 | 国产精品爱久久久久久久 |