最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android 劉海屏適配總結(jié)(推薦)

 更新時(shí)間:2018年07月20日 10:19:27   作者:developerHaoz  
這篇文章主要介紹了Android 劉海屏適配總結(jié)(推薦),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

一、簡(jiǎn)介

隨著 Apple 發(fā)布 iPhone X 之后,各大手機(jī)廠商也開(kāi)始模仿這種劉海屏的設(shè)計(jì),而且劉海屏手機(jī)的用戶也是越來(lái)越大,前段時(shí)間將項(xiàng)目進(jìn)行了所有主流廠商的劉海屏手機(jī)的適配,以便讓劉海屏手機(jī)的用戶也能有更好的體驗(yàn)。

二、劉海屏造成的 UI 顯示問(wèn)題

劉海屏手機(jī)因?yàn)楸绕匠5氖謾C(jī)多了一塊頂部的遮擋性劉海,所以會(huì)造成頂部 Toolbar 以及搜索框的遮擋,而且有些廠商的手機(jī)(vivo、華為),默認(rèn)是在「無(wú)狀態(tài)欄」的界面將狀態(tài)欄進(jìn)行黑化顯示,這時(shí)候會(huì)導(dǎo)致系統(tǒng)下移,從而導(dǎo)致底部的一些 UI 被截?cái)唷3酥?,一些控件的顯示規(guī)則還會(huì)受到影響,如 PopupWindow 的顯示高度會(huì)在「無(wú)狀態(tài)欄」的界面中比普通手機(jī)低一個(gè)「劉海的高度」,從而遮擋住原先在 PopupWindow 周圍的圖標(biāo)。

1、系統(tǒng)下移造成的底部 UI 截?cái)?

小說(shuō)頁(yè)碼被截?cái)?/p>

2、劉海擋住標(biāo)題欄和搜索框

劉海擋住標(biāo)題欄和搜索框

3、PopupWindow 顯示異常

PopupWindow 顯示異常

三、通用的適配方案

理論上來(lái)講,通過(guò) Android P 版本提供的劉海屏相關(guān)接口,判斷手機(jī)是否為劉海屏手機(jī),以及進(jìn)行一些相應(yīng)的處理是最合適的方式,但現(xiàn)在使用在國(guó)內(nèi)使用 Android P 的接口是不現(xiàn)實(shí)的,所以只能通過(guò)各大廠商提供的技術(shù)文檔來(lái)進(jìn)行適配,但適配的流程基本是一致的。

劉海屏的適配流程 

劉海屏的適配流程

其中需要著重處理的是:

1、應(yīng)用是否已經(jīng)適配劉海屏

2、頁(yè)面是否顯示狀態(tài)欄

3.1 應(yīng)用是否已經(jīng)適配劉海屏

現(xiàn)在國(guó)內(nèi)的主流機(jī)型(華為、vivo、OPPO、小米)在劉海屏的顯示上分為兩個(gè)陣營(yíng):

  • 當(dāng)不顯示狀態(tài)欄時(shí),直接將界面進(jìn)行顯示,「狀態(tài)欄原先的位置也用于顯示界面」,例如:OPPO
  • 當(dāng)不顯示狀態(tài)欄時(shí),直接「將狀態(tài)欄原先的位置進(jìn)行黑化,界面整體下移」,例如:華為、vivo

所以,我們?cè)谶M(jìn)行劉海屏適配的時(shí)候,首先需要通過(guò)一些手段,統(tǒng)一各大廠商的顯示方案,讓所有的劉海屏手機(jī)都利用狀態(tài)欄的界面,「告知系統(tǒng)」我們已經(jīng)適配了劉海屏,確保系統(tǒng)不會(huì)下移我們的應(yīng)用,保留原生體驗(yàn)。

這里主要有兩種方式:

1、設(shè)置屏幕高寬比例

因?yàn)閯⒑F潦謾C(jī)的「寬高比」比之前的手機(jī)大,如果不適配的話,Android 默認(rèn)為最大的寬高比為 1.86,

小于劉海屏手機(jī)的寬高比,因此我們需要申明更高的寬高比來(lái)告訴系統(tǒng),我們應(yīng)用已經(jīng)適配了劉海屏。

只要在 AndroidManifest.xml 中加入如下配置:

<meta-data android:name="android.max_aspect" android:value="2.1"/>

也可以在 Application 添加屬性:

android:maxAspectRatio="ratio_float"

ps:這個(gè)屬性需要 API 26 才支持

2、設(shè)置應(yīng)用支持 resize

我們還可以通過(guò)設(shè)置應(yīng)用支持 resizeable,來(lái)告訴系統(tǒng)我們適配了劉海屏,而且這也是 Google 官方推薦的方式。不過(guò)需要注意的是,使用這個(gè)屬性之后,應(yīng)用也會(huì)跟著支持分屏模式。只需要在 AndroidManifest.xml 中添加:

android:resizeableActivity="true"

3.2 頁(yè)面是否顯示狀態(tài)欄

對(duì)于劉海屏適配,我們將界面分為兩種:

  • 對(duì)于有狀態(tài)欄的界面,不會(huì)受到劉海屏的影響
  • 全屏顯示的界面(無(wú)狀態(tài)欄),需要根據(jù)界面的顯示進(jìn)行一些控件的下移

因此,我們進(jìn)行劉海屏適配,其實(shí)針對(duì)的就是沒(méi)有狀態(tài)欄的界面,而有狀態(tài)欄的界面顯示是正常的。對(duì)于沒(méi)有狀態(tài)欄的界面,主要是將對(duì)被劉海遮擋到的控件,設(shè)置對(duì)應(yīng)劉海高度的 MarginTop,從而避免控件被遮擋。而對(duì)于底部可能被截?cái)嗟慕缑妫梢钥紤]將底部做成 ScrollView 的形式。

四、各廠商的適配方案

現(xiàn)在 Android P 的接口還沒(méi)法用,但各手機(jī)廠商都制定了自己的 API,對(duì)此我們需要對(duì)各大機(jī)型進(jìn)行特殊的適配,這里主要介紹 vivo、OPPO、華為 這三種主流手機(jī)的適配方案。

華為

華為作為國(guó)內(nèi)的手機(jī)廠商大頭,自己仿照 Android P 提供的 API,實(shí)現(xiàn)了一套幾乎差不多的 API,所以我們?nèi)绻胍嬖V系統(tǒng)我們的應(yīng)用適配了劉海屏,最好直接使用華為的 API,這樣才是最保險(xiǎn)的。

以下代碼來(lái)自:華為劉海屏適配官方技術(shù)指導(dǎo)

1、應(yīng)用頁(yè)面設(shè)置使用劉海區(qū)顯示

① 方案一:在 AndroidManifest.xml 中增加 meta-data 屬性,此屬性不僅可以針對(duì) Application 生效,也可以對(duì) Activity 配置生效:

<meta-data android:name="android.notch_support" android:value="true"/>

增加這個(gè)屬性之后,系統(tǒng)就會(huì)對(duì)應(yīng)用進(jìn)行下移處理,從而保證原生體驗(yàn)。

② 方案二:通過(guò)添加窗口 FLAG 的方式設(shè)置界面使用劉海區(qū):

public static void setFullScreenWindowLayoutInDisplayCutout(Window window) {
   if (window == null) {
     return;
   }
   WindowManager.LayoutParams layoutParams = window.getAttributes();
   try {
     Class layoutParamsExCls = Class.forName("com.huawei.android.view.LayoutParamsEx");
     Constructor con=layoutParamsExCls.getConstructor(LayoutParams.class);
     Object layoutParamsExObj=con.newInstance(layoutParams);
     Method method=layoutParamsExCls.getMethod("addHwFlags", int.class);
     method.invoke(layoutParamsExObj, FLAG_NOTCH_SUPPORT);
   } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException |InstantiationException 
   | InvocationTargetException e) {
     Log.e("test", "hw add notch screen flag api error");
   } catch (Exception e) {
     Log.e("test", "other Exception");
   }
 }

2、判斷該華為手機(jī)是否劉海屏

public static boolean hasNotchInHuawei(Context context) {
    boolean hasNotch = false;
    try {
      ClassLoader cl = context.getClassLoader();
      Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
      Method hasNotchInScreen = HwNotchSizeUtil.getMethod("hasNotchInScreen");
      if(hasNotchInScreen != null) {
        hasNotch = (boolean) hasNotchInScreen.invoke(HwNotchSizeUtil);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return hasNotch;
  }

3、獲取劉海的高度

public static int[] getNotchSize(Context context) {
     int[] ret = new int[]{0, 0};
     try {
       ClassLoader cl = context.getClassLoader();
       Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
       Method get = HwNotchSizeUtil.getMethod("getNotchSize");
       ret = (int[]) get.invoke(HwNotchSizeUtil);
     } catch (ClassNotFoundException e) {
       Log.e("test", "getNotchSize ClassNotFoundException");
     } catch (NoSuchMethodException e) {
       Log.e("test", "getNotchSize NoSuchMethodException");
     } catch (Exception e) {
       Log.e("test", "getNotchSize Exception");
     } finally {
       return ret;
     }

OPPO

OPPO 是主流廠商中的一股清流,學(xué) iPhoneX 是最像的,OPPO 手機(jī)對(duì)于不顯示狀態(tài)欄的界面,采取的是「狀態(tài)欄原先的位置也用于顯示界面」的方案,所以我們只要進(jìn)行相關(guān)控件的位置移動(dòng)就可以了。

以下代碼來(lái)自:OPPO 凹形屏適配說(shuō)明

1、判斷該 OPPO 手機(jī)是否為劉海屏手機(jī)

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

2、獲取劉海屏的高度

對(duì)于 OPPO 劉海屏手機(jī)的劉海高度,OPPO 官方的文檔沒(méi)有提供相關(guān)的 API,但官方文檔表示 OPPO 手機(jī)的劉海高度和狀態(tài)欄的高度是一致的,而且我也對(duì)此進(jìn)行了驗(yàn)證,確實(shí)如此。所以我們可以直接獲取狀態(tài)欄的高度,作為 OPPO 手機(jī)的劉海高度。

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

vivo

vivo 提供的技術(shù)文檔對(duì)于開(kāi)發(fā)者來(lái)說(shuō)是最不友好的,只提供了一個(gè) API 來(lái)進(jìn)行劉海屏的判斷,并沒(méi)有提供劉海高度的獲取方式,我們只能通過(guò)獲取狀態(tài)欄高度來(lái)當(dāng)做劉海的高度,但在某些機(jī)型可能會(huì)有些偏差。

官方文檔: vivo 手機(jī)適配指南

判斷該 vivo 手機(jī)是否為劉海屏手機(jī)

public static boolean hasNotchInVivo(Context context) {
    boolean hasNotch = false;
    try {
      ClassLoader cl = context.getClassLoader();
      Class ftFeature = cl.loadClass("android.util.FtFeature");
      Method[] methods = ftFeature.getDeclaredMethods();
      if (methods != null) {
        for (int i = 0; i < methods.length; i++) {
          Method method = methods[i];
          if(method != null) {
            if (method.getName().equalsIgnoreCase("isFeatureSupport")) {
              hasNotch = (boolean) method.invoke(ftFeature, 0x00000020);
              break;
            }
          }
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
      hasNotch = false;
    }
    return hasNotch;
  }

五、總結(jié)

以上便是在之前在進(jìn)行 Android 劉海屏適配的時(shí)候,所積累的一些經(jīng)驗(yàn)和心得。將其記錄下來(lái),以便自己以后進(jìn)行回顧,同時(shí)也希望這篇文章能對(duì)進(jìn)行劉海屏適配的同學(xué)一些幫助。也希望大家多多支持腳本之家。

相關(guān)文章

  • 深入Android SQLite 事務(wù)處理詳解

    深入Android SQLite 事務(wù)處理詳解

    本篇文章是對(duì)Android中SQLite 事務(wù)處理進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下
    2013-05-05
  • android操作XML的幾種方法總結(jié)

    android操作XML的幾種方法總結(jié)

    在android中,操作xml文件,一般有幾種方式:SAX操作,Pull操作,DOM操作等。其中DOM的方式,可能是大家最熟悉的,也是符合W3C標(biāo)準(zhǔn)的
    2013-10-10
  • Android四大組件之Activity詳解

    Android四大組件之Activity詳解

    今天小編就為大家分享一篇關(guān)于Android四大組件之Activity詳解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • Android徹底清除APP數(shù)據(jù)的兩種方案總結(jié)

    Android徹底清除APP數(shù)據(jù)的兩種方案總結(jié)

    大家在用Android手機(jī)的時(shí)候肯定都遇到過(guò)內(nèi)存剩余空間越來(lái)越小的情況,所以下面這篇文章主要給大家介紹了關(guān)于Android徹底清除APP數(shù)據(jù)的兩種方案,需要的朋友可以參考下
    2021-11-11
  • MotionLayout自定義開(kāi)關(guān)按鈕實(shí)例詳解

    MotionLayout自定義開(kāi)關(guān)按鈕實(shí)例詳解

    這篇文章主要為大家介紹了MotionLayout自定義開(kāi)關(guān)按鈕實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Android獲取棧頂?shù)膽?yīng)用包名方法

    Android獲取棧頂?shù)膽?yīng)用包名方法

    下面小編就為大家分享一篇Android獲取棧頂?shù)膽?yīng)用包名方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • Android WebView如何判定網(wǎng)頁(yè)加載的錯(cuò)誤

    Android WebView如何判定網(wǎng)頁(yè)加載的錯(cuò)誤

    這篇文章主要介紹了Android WebView如何判定網(wǎng)頁(yè)加載的錯(cuò)誤,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下
    2021-04-04
  • Flutter使用NetworkImage實(shí)現(xiàn)圖像顯示效果

    Flutter使用NetworkImage實(shí)現(xiàn)圖像顯示效果

    這篇文章主要為大家介紹了如何在Flutter中使用NetworkImage實(shí)現(xiàn)圖像顯示效果,文中的示例代碼講解詳細(xì),快跟隨小編一起學(xué)習(xí)一下吧
    2022-04-04
  • 使用Retrofit下載文件并實(shí)現(xiàn)進(jìn)度監(jiān)聽(tīng)的示例

    使用Retrofit下載文件并實(shí)現(xiàn)進(jìn)度監(jiān)聽(tīng)的示例

    這篇文章主要介紹了使用Retrofit下載文件并實(shí)現(xiàn)進(jìn)度監(jiān)聽(tīng)的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • DialogFragment運(yùn)行原理及使用方法詳解

    DialogFragment運(yùn)行原理及使用方法詳解

    這篇文章主要介紹了DialogFragment運(yùn)行原理及使用方法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10

最新評(píng)論

革吉县| 如皋市| 湟源县| 静安区| 资兴市| 三河市| 平顶山市| 科技| 永春县| 江津市| 永川市| 浦县| 社会| 同仁县| 八宿县| 颍上县| 佛山市| 栾川县| 武宁县| 台州市| 清远市| 桂阳县| 凤庆县| 天门市| 宁国市| 新和县| 雷州市| 酒泉市| 乳山市| 顺义区| 舞阳县| 阜新市| 遂宁市| 新巴尔虎左旗| 和平县| 通榆县| 松潘县| 通化县| 平果县| 阿拉善盟| 巧家县|