支援螢幕凹口

試用 Compose
Jetpack Compose 是 Android 推薦的 UI 工具包。瞭解如何在 Compose 中使用螢幕凹口。

「螢幕凹口」是部分裝置延伸至顯示介面的區域。不僅能享有無邊框體驗,同時也能為裝置正面的重要感應器提供空間。

在搭載 Android 9 (API 級別 28) 以上版本的裝置上,Android 支援螢幕凹口。不過,在搭載 Android 8.1 以下版本的裝置上,裝置製造商也支援螢幕凹口。

本文說明如何實作有凹口裝置的支援功能,包括如何使用「剪裁區域」(在包含凹口的螢幕表面的無邊框矩形)。

圖片:中央螢幕凹口示例
圖 11 螢幕凹口。

選擇應用程式處理凹口區域的方式

如果不希望內容與凹口區域重疊,通常只要確保內容不會與狀態列和導覽列重疊。如果您要算繪到凹口區域,請使用 WindowInsetsCompat.getDisplayCutout() 擷取 DisplayCutout 物件,其中包含每個凹口的安全插邊和定界框。這些 API 可讓您檢查內容是否與凹口重疊,以便視需要重新調整位置。

此外,也能判斷內容是否在凹口區域後方。layoutInDisplayCutoutMode 視窗版面配置屬性可控制內容在凹口區域中繪製的方式。您可以將 layoutInDisplayCutoutMode 設為下列任一值:

您可以透過程式輔助,或在活動中設定樣式來設定凹口模式。下例會定義將 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 屬性套用至活動的樣式。

<style name="ActivityTheme">
  <item name="android:windowLayoutInDisplayCutoutMode">
    shortEdges <!-- default, shortEdges, or never -->
  </item>
</style>

以下各節將詳細說明各種凹口模式。

預設行為

根據預設,在未設定特殊旗標的情況下,在直向模式下,裝置的狀態列會經過調整,至少與凹口大小相同,您的內容會顯示在下方區域。在橫向或全螢幕模式下,應用程式視窗會加上黑邊,因此所有內容都不會顯示在凹口區域。

在短邊緣凹口區域顯示內容

對於部分內容 (例如影片、相片、地圖和遊戲) 來說,在凹口區域算繪是為使用者提供更身歷其境的無邊框體驗的絕佳方式。使用 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 時,無論系統資訊列為隱藏或可見,內容都會在螢幕短邊緣和橫向螢幕上延伸至螢幕短邊的凹口區域。使用這種模式時,請確定沒有任何重要內容與凹口區域重疊。

下圖為直向裝置的 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 範例:

以直向模式將內容算繪到凹口區域的圖片
圖 2 以直向模式將內容算繪到凹口區域。

下圖為橫向裝置的 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 範例:

以橫向模式將內容算繪到凹口區域的圖片
圖 3. 以橫向模式將內容算繪到凹口區域。

在這個模式下,無論視窗是否隱藏系統資訊列,視窗都會在螢幕短邊和橫向畫面中,延伸至螢幕短邊緣。

角落的凹口即為短邊緣:

圖片:裝置有角落凹口
圖 4. 配備角落凹槽的裝置。

一律不在螢幕凹口區域中顯示內容

如果使用 LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER,則視窗不得與凹口區域重疊。

以下是直向的 LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER 範例:

顯示直向 LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER 的圖片
圖 5. 直向模式的 LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER 範例。

以下是橫向模式的 LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER 範例:

顯示橫向的 LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER 的圖片
圖 6. 橫向模式的 LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER 範例。

支援螢幕凹口支援的最佳做法

使用螢幕凹口時,請考慮以下幾點:

  • 留意放置 UI 的重要元素。請勿讓裁剪區域遮蓋任何重要的文字、控制項或其他資訊。
  • 請勿在凹口區域放置或擴充任何需要精細辨識的互動元素,凹口區域的觸控敏感度可能較低。
  • 請盡可能使用 WindowInsetsCompat 擷取狀態列高度,並決定適合套用至內容的適當邊框間距。請避免對狀態列高度進行硬式編碼,以免內容重疊或遭到截斷。

    圖片:內容因插邊設定不當而從頂端裁剪
    圖 7.請使用 WindowInsetsCompat 避免重疊或切斷內容。
  • 請使用 View.getLocationInWindow() 判斷應用程式正在使用的視窗空間。請勿假設應用程式正在使用整個視窗,請勿使用 View.getLocationOnScreen()

  • 如果應用程式需要轉換到沉浸模式,請使用 shortEdgesnever 凹口模式。預設凹口行為可能會導致應用程式內容在系統資訊列顯示時在螢幕凹口區域顯示,但在沉浸模式下則不行。這會導致內容在轉換期間上下移動,如以下範例所示。

    這張圖片顯示內容在轉場期間上下移動。
    圖 8.內容在轉換期間上下移動的範例。
  • 在沉浸模式下,使用視窗座標時請務必小心,因為應用程式加上上下黑邊時,不會使用整個螢幕。因為使用上下方塊,螢幕原點的座標與視窗起點的座標不同。您可以視需要使用 getLocationOnScreen(),將螢幕座標轉換為檢視畫面座標。下圖顯示內容加上黑邊時的座標差異:

    這張圖片顯示在內容加上黑邊時,視窗和螢幕座標。
    圖 9.內容加上黑邊時,視窗座標與畫面座標。
  • 處理 MotionEvent 時,請使用 MotionEvent.getX()MotionEvent.getY(),避免類似的座標問題。請勿使用 MotionEvent.getRawX()MotionEvent.getRawY()

測試內容轉譯方式

測試應用程式的所有畫面和體驗。請盡可能使用不同類型的凹口裝置進行測試。如果您沒有有凹口的裝置,可以在搭載 Android 9 以上版本的任何裝置或模擬器中,模擬常見的凹口設定,步驟如下:

  1. 啟用開發人員選項
  2. 在「Developer options」畫面中,向下捲動至「Drawing」部分,然後選取「Simulate a display withCutout」
  3. 選取凹口類型。

    圖片:如何在模擬器中模擬螢幕凹口
    圖 10.開發人員選項,可測試內容算繪方式。

其他資源