支援螢幕凹口

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

螢幕凹口是部分裝置上的區域,會擴展到螢幕表面。這種 API 可提供無邊框體驗,同時在裝置前方為重要感應器提供空間。

Android 支援在搭載 Android 9 (API 級別 28) 以上版本的裝置上出現螢幕凹口。不過,裝置製造商也支援在搭載 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 with the Deout」
  3. 選取凹口類型。

    這張圖片說明如何在模擬器中模擬螢幕凹口
    圖 10.開發人員選項,用於測試內容轉譯方式。

其他資源