詳解Android劉海屏適配

      網(wǎng)友投稿 965 2022-05-29

      Apple一直在引領(lǐng)設(shè)計(jì)的潮流,自從 iPhone X 發(fā)布之后,”劉海屏” 就一直存在爭(zhēng)議,本以為是一個(gè)美麗的錯(cuò)誤(Bug),卻早就了一時(shí)間“劉海屏”的模仿潮。目前,國內(nèi)已經(jīng)推出的劉海屏”手機(jī)有 OPPO R15 和 華為 P20,并且Google也在IO大會(huì)上提高了相應(yīng)的適配方案。

      什么是劉海屏

      屏幕的正上方居中位置(下圖黑***域)會(huì)被挖掉一個(gè)孔,屏幕被挖掉的區(qū)域無法正常顯示內(nèi)容,這種類型的屏幕就是劉海屏,也有其他叫法:挖孔屏、凹凸屏等等,這里統(tǒng)一按劉海屏命名。

      詳解Android劉海屏適配

      就現(xiàn)在市場(chǎng)上的情況來說,“劉海屏”主要分成兩類,一類是標(biāo)準(zhǔn)的 Android P Api,另外一類就是廠商在 Android P 以下的系統(tǒng),做的特殊適配。

      例如:華為 P20 就是采用的 Android P 標(biāo)準(zhǔn) Api 的方式,而 OPPO R15 就不一樣了,它有自己的適配 Api。

      如何適配劉海屏

      由于Android p正式版前兩天才發(fā)布, 當(dāng)前市面上的Android 劉海屏手機(jī)還不能用Android 官方提供的方案來解決,那怎么辦呢?還好幾個(gè)廠商自己給出了適配方案(文末會(huì)接受使用Android P來適配劉海屏)。

      華為P20

      華為早在iPhone X發(fā)布后不久就推出了“劉海屏”P20,華為劉海屏適配官方文檔:

      https://devcenter-test.huawei.com/consumer/cn/devservice/doc/50114

      華為給出的文檔最為詳細(xì)適配文檔,P20 pro預(yù)裝系統(tǒng)對(duì)未做劉海屏適配處理的app有一定處理,處理的邏輯如下圖。

      右上圖可知,華為系統(tǒng)做偏移處理的有以下2種情況:

      1.未設(shè)置meta-data值,頁面橫屏狀態(tài)

      2.未設(shè)置meta-data值,頁面豎屏狀態(tài),不顯示狀態(tài)欄

      適配劉海屏主要有以下幾個(gè)步驟:

      1.配置meta-data

      華為新增的Meta-data屬性android.notch_support在應(yīng)用的AndroidManifest.xml中增加meta-data屬性,此屬性不僅可以針對(duì)Application生效,也可以對(duì)Activity配置生效,具體方式如下所示:

      1

      ①對(duì)Application生效,意味著該應(yīng)用的所有頁面,系統(tǒng)都不會(huì)做豎屏場(chǎng)景的特殊下移或者是橫屏場(chǎng)景的右移特殊處理:

      ② 對(duì)Activity生效,意味著可以針對(duì)單個(gè)頁面進(jìn)行劉海屏適配,設(shè)置了該屬性的Activity系統(tǒng)將不會(huì)做特殊處理:

      2.檢測(cè)是否存在劉海屏

      3.獲取劉海屏的參數(shù)

      4. UI適配

      通過增加上面適配方案提到的配置(meta-data或者是Flag),應(yīng)用在華為劉海屏手機(jī)上就能夠默認(rèn)使用劉海區(qū)顯示了,但是為了避免出現(xiàn)UI被劉海區(qū)遮擋的問題,還是需要應(yīng)用自己做一些額外的UI適配工作:

      (1)判斷是否劉海屏,通過華為劉海屏SDK的API判斷,具體參考3.2.1章節(jié)

      (2)如果是劉海屏手機(jī)需要應(yīng)用自己調(diào)整布局避開劉海區(qū),布局原則:保證重要的文字、圖片和視頻信息、可點(diǎn)擊的控件和圖標(biāo)還有應(yīng)用彈窗等等布局建議顯示在狀態(tài)欄區(qū)域以下(安全區(qū)域);不重要,遮擋不會(huì)出現(xiàn)問題的布局可以延伸到狀態(tài)欄區(qū)域(危險(xiǎn)區(qū)域)顯示,按照這種布局原則修改,可以一次修改就能適配所有的劉海屏手機(jī):

      獲取系統(tǒng)狀態(tài)欄高度接口:

      public?static?int?getStatusBarHeight(Context?context)?{????int?result?=?0;????int?resourceId?=?context.getResources().getIdentifier("status_bar_height",?"dimen",?"android");????if?(resourceId?>?0)?{ ????????result?=?context.getResources().getDimensionPixelSize(resourceId); ????}????return?result; }12345678

      關(guān)于更詳細(xì)的適配資料,可以訪問華為劉海屏適配技術(shù)文檔。

      vivo & OPPO

      vivo 和 OPPO官網(wǎng)僅僅給出了適配指導(dǎo),沒有給出具體方案,簡單總結(jié)為:

      如有是具有劉海屏的手機(jī),豎屏顯示狀態(tài)欄,橫屏不要在危險(xiǎn)區(qū)顯示重要信息或者設(shè)置點(diǎn)擊事件。官方的文檔地址如下:

      oppo官方文檔:

      https://open.oppomobile.com/service/message/detail?id=61876

      vivo官方文檔:

      https://dev.vivo.com.cn/doc/document/info?id=103

      首先,判斷是不是劉海屏手機(jī)。

      OPPO判斷方法:

      public?static?boolean?hasNotchInOppo(Context?context){???return?context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism"); }123

      vivo的判斷方法:

      public?static?final?int?NOTCH_IN_SCREEN_VOIO=0x00000020;//是否有凹槽public?static?final?int?ROUNDED_IN_SCREEN_VOIO=0x00000008;//是否有圓角public?static?boolean?hasNotchInScreenAtVoio(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); ???}?catch?(ClassNotFoundException?e) ???{?Log.e("test",?"hasNotchInScreen?ClassNotFoundException");?}???catch?(NoSuchMethodException?e) ???{?Log.e("test",?"hasNotchInScreen?NoSuchMethodException");?}???catch?(Exception?e) ???{?Log.e("test",?"hasNotchInScreen?Exception");?}???finally ???{?return?ret;?} }12345678910111213141516171819

      然后在進(jìn)行適配,官方這方面的資料很少也不是很詳細(xì)

      google官方

      google從Android P開始為劉海屏提供支持,目前提供了一個(gè)類和三種模式:

      一個(gè)類指的是可以用DisplayCutout這個(gè)類找出劉海(cutout)的位置和形狀,調(diào)用getDisplayCutout()這個(gè)方法可以獲取劉海(cutout)的位置和區(qū)域。例如:

      DisplayCutout?cutout?=?mContext.getDisplayCutout();1

      Google官方提供了三種模式,分別是:

      LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT:僅僅當(dāng)系統(tǒng)提供的bar完全包含了劉海區(qū)時(shí)才允許window擴(kuò)展到劉海區(qū),否則window不會(huì)和劉海區(qū)重疊

      LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES:允許window擴(kuò)展到劉海區(qū)(原文說的是短邊的劉海區(qū), 目前有劉海的手機(jī)都在短邊,所以就不糾結(jié)了)

      LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER:不允許window擴(kuò)展到劉海區(qū)。

      例如,下面是可以設(shè)置是否允許window擴(kuò)展到劉海區(qū)的代碼。

      WindowManager.LayoutParams?lp?=getWindow().getAttributes();??lp.layoutInDisplayCutoutMode=WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;??getWindow().setAttributes(lp);1234

      一個(gè)有狀態(tài)欄的頁面, 我們可以這樣適配:

      DisplayCutout?cutout?=?getDisplayCutout();if(cutout?!=?null){ ?WindowManager.LayoutParams?lp?=getWindow().getAttributes();?? ?lp.layoutInDisplayCutoutMode=WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;?? ?getWindow().setAttributes(lp);}123456

      當(dāng)然如果你身邊還沒有劉海屏手機(jī),可以使用Android P提供的模擬器,更新SDK到Android P preview版本。

      然后,可以通過開發(fā)者選項(xiàng)里的 “Simulate a display with a cutout”,開啟劉海屏的支持,并且劉海屏有多個(gè)版本,需要注意它們的區(qū)別。

      軟件開發(fā) 前端開發(fā)

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:一文打通Seata源碼的任督二脈
      下一篇:學(xué)習(xí)第三天:關(guān)于【Java并發(fā)編程之深入理解】Synchronized的使用
      相關(guān)文章
      亚洲精品欧洲精品| 亚洲网站在线观看| 99热亚洲色精品国产88| 亚洲AV无码精品色午夜果冻不卡| 亚洲AV无码成H人在线观看| 久久精品国产亚洲AV未满十八| 亚洲人成网亚洲欧洲无码| 亚洲色偷精品一区二区三区 | 亚洲成_人网站图片| 亚洲精品国产日韩| 亚洲乱码在线卡一卡二卡新区| 中文字幕亚洲精品资源网| 亚洲国产精品婷婷久久| 亚洲色图在线观看| 777亚洲精品乱码久久久久久 | 久久精品国产亚洲精品2020| 久久精品国产亚洲AV电影| 91亚洲精品视频| 亚洲黄色在线视频| 亚洲国产精品线观看不卡| 亚洲Av无码一区二区二三区| 波多野结衣亚洲一级| 亚洲熟妇AV一区二区三区宅男| 亚洲国产午夜精品理论片在线播放 | 亚洲欭美日韩颜射在线二| 亚洲精品无码av人在线观看| 亚洲av永久无码精品网站| 伊人久久综在合线亚洲2019| 亚洲无成人网77777| 亚洲偷自精品三十六区| 亚洲heyzo专区无码综合| 国产成人精品亚洲| 2048亚洲精品国产| 亚洲爆乳精品无码一区二区三区| 亚洲AV午夜成人片| 亚洲精品在线免费看| 日韩亚洲人成在线| 国产成人va亚洲电影| 中国亚洲女人69内射少妇| 五月天网站亚洲小说| 亚洲成AV人片久久|