1. 程式人生 > >android相容小米xiaomi劉海屏解決方案

android相容小米xiaomi劉海屏解決方案

推薦:

目錄:

背景

小米 MIUI Notch 屏 Android O 適配說明
1.目前已上市的小米 Notch 裝置(俗稱劉海屏手機)如下,其寬度、高度和形狀均略有差異。

android劉海屏dujinyang

2.含 Notch 往往都是全面屏手機,即螢幕比例可能是18:9、18.7:9 等不同的值。

3.Android P 提供了 Notch / 劉海屏的標準適配介面

MIUI 也將在 Android P 上採用標準介面,因此,下文提及的介面僅用於 Android O 上。關於 Android P 的介面說明,詳見後文。

4.如下圖,為便於說明,我們將頂部區域定義為「Notch」和「耳朵區」。
android劉海屏奧特曼超人

系統級適配規則

Notch 機型在介面上會帶來兩個問題:

  • 頂部內容會被 Notch 遮擋
  • 如何處理耳朵區的顯示區域

為了保證絕大部分應用都能正常顯示,同時儘可能利用螢幕的顯示區域。MIUI System UI 制定了以下全域性規則:

  • status bar 略高於 Notch 高度,對於應用來說,相當於一個更高的 status bar。
  • 當應用顯示 status bar 時(如微信首頁),允許應用使用耳朵區(背後的邏輯是:因為 status bar 區域本身不可互動,且會顯示訊號、電池等資訊,因此我們假定應用不會在該區域放置重要的內容和可互動的控制元件)。
  • 當應用不顯示 status bar 時(如全屏遊戲),不允許應用使用耳朵區,系統預設填黑。
  • 橫屏時,預設均不允許使用耳朵區,系統預設填黑。
  • 不允許應用180度倒轉顯示。

注:上述規則的模擬效果對比圖,可以參見文末的附件「Notch 屏系統預設規則介紹」。

開發者適配

系統規則只能解決最基礎的可用性問題,在系統規則下,開發者仍需要檢查以下內容:

  • 檢查系統預設規則是否有可用性問題,考慮是否做針對性優化。
  • 檢查 status bar 的顯示策略。重新考慮是否隱藏 status bar
  • 儘量避免某些頁面顯示 status bar,某些頁面又隱藏,否則會出現頁面跳變的情況(應用的可用高度變了)。
  • 檢查橫屏的情況,確定是否需要利用橫屏的Notch,若使用,需兼顧 Notch 出現在左邊/右邊的情況。
  • 檢查是否寫死了狀態列的高度值。Notch機器狀態列的值是變化的,建議改為讀取系統的值(後有相關方法說明)。
  • 檢查開啟「隱藏螢幕劉海」後,應用是否顯示異常(詳見後文)。

系統介面說明

若開發者對系統規則下的效果不滿意,可以呼叫以下介面,做針對性的優化。

1.如何判斷裝置為 Notch 機型

系統增加了 property ro.miui.notch,值為1時則是 Notch 屏手機。

SystemProperties.getInt("ro.miui.notch", 0) == 1;

2.Application 級別的控制介面

如果開發者認為應用的所有頁面統一處理就行,可以使用該介面。在 Application 下增加一個 meta-data,用以宣告該應用是否使用耳朵區。示例如下:

<meta-data
 android:name="notch.config"
 android:value="portrait|landscape"/>

其中,value 的取值可以是以下4種:

"none" 橫豎屏都不繪製耳朵區
"portrait" 豎屏繪製到耳朵區
"landscape" 橫屏繪製到耳朵區
"portrait|landscape" 橫豎屏都繪製到耳朵區

注:一旦開發者聲明瞭meta-data,系統就會優先遵從開發者的宣告。

3.Window 級別的控制介面

如果開發者希望對特定 Window 作處理,可以使用該介面。 在 WindowManager.LayoutParams 增加 extraFlags 成員變數,用以宣告該 window 是否使用耳朵區。

其中,extraFlags 有以下變數:

  • 0x00000100 開啟配置
  • 0x00000200 豎屏配置
  • 0x00000400 橫屏配置

組合後表示 Window 的配置,如:

0x00000100 | 0x00000200 豎屏繪製到耳朵區
0x00000100 | 0x00000400 橫屏繪製到耳朵區
0x00000100 | 0x00000200 | 0x00000400 橫豎屏都繪製到耳朵區

控制 extraFlags 時注意只控制這幾位,不要影響其他位。可以用 Window 的 addExtraFlags 和 clearExtraFlags 來修改, 這兩個方法是 MIUI 增加的方法,需要反射呼叫。

int flag = 0x00000100 | 0x00000200 | 0x00000400;
try {
    Method method = Window.class.getMethod("addExtraFlags",
            int.class);
    method.invoke(getWindow(), flag);
} catch (Exception e) {
    Log.i(TAG, "addExtraFlags not found.");
}

4.狀態列高度獲取方法

由於 Notch 裝置的狀態列高度與正常機器不一樣,因此在需要使用狀態列高度時,不建議寫死一個值,而應該改為讀取系統的值。

以下是獲取當前裝置狀態列高度的方法:

int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
    result = context.getResources().getDimensionPixelSize(resourceId);
}

5.如何測試

使用 小米 8 ,升級至最新MIUI版本即可。

「隱藏螢幕劉海」適配

MIUI 針對 Notch 裝置,有一個「隱藏螢幕劉海」的設定項(設定-全面屏-隱藏螢幕劉海),具體表現是:系統會強制蓋黑狀態列(無視應用的Notch使用宣告),視覺上達到隱藏劉海的效果。但會給某些應用帶來適配問題(控制元件/內容遮擋或過於靠邊等)。

因此開發者在適配時,還需要檢查開啟「隱藏螢幕劉海」後,應用的頁面是否顯示正常。針對有問題的頁面,我們建議:

1.請通過以下方法獲取系統狀態列高度,然後據此調整佈局,而不是寫死佈局:

int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
    result = context.getResources().getDimensionPixelSize(resourceId);
}

2.如有需要,可以通過查詢以下 Global settings 來確定「隱藏螢幕劉海」是否開啟了,然後再作針對性優化。

Settings.Global.getInt(mContext.getContentResolver(), "force_black", 0) == 1

關於 Android P 的適配

由於 Android P 已針對異形螢幕提供了標準的介面,因此 MIUI 在後續升級到 Android P 時,將會完全複用 Android P 的介面和邏輯。不過仍有幾點值得注意:

1.由於 MIUI Android O 的介面能力與 Android P 有差異,無法二者完全相容。所以上述提到的介面,在升級到 Android P 後將不再生效,開發者需要針對 Android P 重新適配,望各位開發者諒解。

2.同時,由於執行 MIUI Android O 的劉海屏裝置還會存在好幾年,開發者在程式碼上,仍需要保留對 MIUI Android O 的適配邏輯。

由於 Android P 的介面公佈得較晚,我們沒法做到和 Android P 完全相容。給各位開發者造成不便,再次表示歉意。

附:系統預設規則的說明

如果開發者未做任何宣告,系統也會有一套預設的顯示規則,下圖說的就是這套規則,增加示意圖方便大家理解。
安卓劉海屏奧特曼超人米奇雲科技