自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

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

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

[[260668]]

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

ok,廢話說完了,開始適配。

首先要清楚的是哪些界面需要適配劉海屏:

  • 有狀態(tài)欄的界面:劉海區(qū)域會顯示狀態(tài)欄,無需適配
  • 全屏界面:劉海區(qū)域可能遮擋內(nèi)容,需要適配

如果你的應(yīng)用里所有界面都有狀態(tài)欄,那么恭喜你,你不用做任何操作,狀態(tài)欄就那么自然的顯示在劉海區(qū)域,毫無違和,劉海屏已適配完畢,可以點(diǎn)叉出去了。

不幸的是,你的應(yīng)用中很大幾率會有全屏界面,所謂的劉海屏適配,也正是針對這些全屏界面。

如果你什么都不做,默認(rèn)規(guī)則不允許全屏界面內(nèi)容顯示到劉海區(qū)域,即劉海屏區(qū)域會保留一條黑邊,你的全屏界面會在劉海下方展示,這看起來好像也是可以接受的,然后你竟說服產(chǎn)品達(dá)成共識,“無為而治”才是***大的劉海屏適配方案!

但有些手機(jī)廠商(譬如oppo)不開心了,我辛辛苦苦研發(fā)的劉海屏手機(jī),你們這些開發(fā)者竟直接放棄劉海區(qū)域!然后就在你的全屏界面下方加了一條提示:“全屏顯示”,當(dāng)用戶點(diǎn)擊開啟后,強(qiáng)行把你的全屏界面顯示到劉海區(qū)域,然后一切都亂套了...

嗯~ “無為而治”行不通。

只能允許全屏界面內(nèi)容顯示到劉海區(qū)域了,參考各大廠商的適配文檔,我們可以知道如何允許,比如華為機(jī)型只需在 AndroidManifest 中配置:

配置后,華為機(jī)型上的全屏界面就會顯示到劉海區(qū)域了,但這個劉海,是可能擋住我們?nèi)两缑嬷械膬?nèi)容的。這時需要將全屏界面中的視圖元素適當(dāng)下移,保證不會被劉海遮擋住,就 ok 了。

這里我們搞清楚:允許全屏界面內(nèi)容顯示到劉海區(qū)域的機(jī)型,才需要將全屏界面中的視圖元素適當(dāng)下移。

比如若只允許華為機(jī)型全屏界面內(nèi)容顯示到劉海區(qū)域,那只有華為的劉海屏機(jī)型才需要將全屏界面中的視圖元素適當(dāng)下移,其他廠商的劉海屏機(jī)型則不需要下移。

如果允許華為、小米、oppo、vivo 全屏界面內(nèi)容顯示到劉海區(qū)域,那么華為、小米、oppo、vivo 劉海屏機(jī)型需要將全屏界面中的視圖元素適當(dāng)下移。

另外也不一定要通過全屏界面中的視圖元素適當(dāng)下移方式來適配劉海屏,如果產(chǎn)品形態(tài)允許的話,你也可以讓該界面顯示狀態(tài)欄啊。

至此劉海屏適配完畢,是不是很簡單!?

***代碼奉上,拿走不謝:

1、允許全屏界面內(nèi)容顯示到劉海區(qū)域配置:

  1. <!--允許繪制到oppo、vivo劉海屏機(jī)型的劉海區(qū)域 --> 
  2. <meta-data 
  3.     android:name="android.max_aspect" 
  4.     android:value="2.2" /> 
  5.  
  6. <!-- 允許繪制到華為劉海屏機(jī)型的劉海區(qū)域 --> 
  7. <meta-data 
  8.     android:name="android.notch_support" 
  9.     android:value="true" /> 
  10.  
  11. <!-- 允許繪制到小米劉海屏機(jī)型的劉海區(qū)域 --> 
  12. <meta-data 
  13.     android:name="notch.config" 
  14.     android:value="portrait" /> 

上面在 AndroidManifest 的配置在 Android 9.0 之前有效,9.0 系統(tǒng)針對劉海屏制定了新的 api,默認(rèn)保留一條黑邊,即不允許繪制到劉海區(qū)域。所以如果你還沒有適配 Android 9.0,那在判斷是否是允許全屏界面內(nèi)容顯示到劉海區(qū)域的劉海屏機(jī)型時,就要加上版本判斷。

2、判斷是否是允許全屏界面內(nèi)容顯示到劉海區(qū)域的劉海屏機(jī)型:

  1. public class CutoutUtil { 
  2.  
  3.     private static Boolean sAllowDisplayToCutout; 
  4.  
  5.     /** 
  6.      * 是否為允許全屏界面顯示內(nèi)容到劉海區(qū)域的劉海屏機(jī)型(與AndroidManifest中配置對應(yīng)) 
  7.      */ 
  8.     public static boolean allowDisplayToCutout() { 
  9.         if (sAllowDisplayToCutout == null) { 
  10.             if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O_MR1) { 
  11.                 // 9.0系統(tǒng)全屏界面默認(rèn)會保留黑邊,不允許顯示內(nèi)容到劉海區(qū)域 
  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.      * 是否是華為劉海屏機(jī)型 
  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劉海屏機(jī)型 
  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劉海屏機(jī)型 
  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.      * 是否是小米劉海屏機(jī)型 
  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.             //參數(shù) 
  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.  

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

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

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

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

  1. public interface CutoutAdapt { 

然后在 ActivityLifecycleCallbacks 回調(diào),統(tǒng)一適配允許通過顯示狀態(tài)欄的全屏界面:

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

 【編輯推薦】

責(zé)任編輯:未麗燕 來源: 簡書
相關(guān)推薦

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

2019-04-01 14:59:56

負(fù)載均衡服務(wù)器網(wǎng)絡(luò)

2018-04-12 14:56:49

Android劉海屏技巧

2015-10-28 13:57:29

融合架構(gòu)華三UIS

2021-09-07 09:40:20

Spark大數(shù)據(jù)引擎

2022-06-16 07:31:41

Web組件封裝HTML 標(biāo)簽

2024-06-19 09:58:29

2023-04-12 11:18:51

甘特圖前端

2009-09-25 08:38:25

Hibernate數(shù)據(jù)

2024-05-13 09:28:43

Flink SQL大數(shù)據(jù)

2012-07-10 01:22:32

PythonPython教程

2015-09-06 09:22:24

框架搭建快速高效app

2023-11-30 10:21:48

虛擬列表虛擬列表工具庫

2020-12-18 11:46:25

人工智能人工智能技術(shù)

2013-11-18 13:46:56

2022-04-06 16:43:38

戴爾

2023-07-15 18:26:51

LinuxABI
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號