螢幕凹口是某些裝置上延伸至螢幕表面的區域。可提供無邊框體驗,同時為裝置正面的重要感應器保留空間。
Android 支援在搭載 Android 9 (API 級別 28) 以上版本的裝置上顯示螢幕凹口。不過,裝置製造商也可以在搭載 Android 8.1 以下版本的裝置上支援螢幕凹口。
本文說明如何實作支援有凹口的裝置,包括如何使用凹口區域,也就是螢幕表面上包含凹口的無邊框矩形。
選擇應用程式處理凹口區域的方式
如要避免內容與凹口區域重疊,一般來說,只要確保內容不會與狀態列和導覽列重疊即可。如要將內容算繪到凹口區域,請使用 WindowInsetsCompat.getDisplayCutout() 擷取 DisplayCutout 物件,其中包含每個凹口的安全性插邊和定界框。這些 API 可讓您檢查內容是否與凹口重疊,以便視需要重新調整位置。
您也可以決定內容是否要顯示在凹口區域後方。layoutInDisplayCutoutMode
視窗版面配置屬性可控制內容在凹口區域的繪製方式。
您可以將 layoutInDisplayCutoutMode 設為下列任一值:
LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT:如果系統資訊列包含螢幕凹口,內容會顯示在凹口區域。否則視窗不會與螢幕凹口重疊;舉例來說,以橫向模式顯示時,內容可能會出現上下黑邊。如果應用程式的目標是 SDK 35,系統會將此解讀為ALWAYS(適用於非浮動視窗)。LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS:內容一律可延伸至凹口區域。如果應用程式以 SDK 35 為目標版本,且在 Android 15 裝置上執行,這是非浮動視窗唯一允許的模式,可確保顯示無邊框畫面。LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES: 在直向和橫向模式下,內容都會轉譯到凹口區域。請勿用於浮動視窗。如果應用程式指定 SDK 35,系統會將此值解讀為非浮動視窗的ALWAYS。LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER: 內容絕不會在螢幕凹口區域中顯示。如果應用程式指定 SDK 35,系統會將此解讀為非浮動視窗的ALWAYS。
您可以透過程式輔助方式設定凹口模式,或是在活動中設定樣式。下列範例定義樣式,將 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 屬性套用至活動。
<style name="ActivityTheme"> <item name="android:windowLayoutInDisplayCutoutMode"> shortEdges <!-- default, shortEdges, or never --> </item> </style>
以下各節將詳細說明不同的剪裁模式。
預設行為
如果應用程式以 SDK 35 為目標版本,且在 Android 15 裝置上執行,則 LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS 是預設行為,且系統會將 LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT 解讀為非浮動視窗的 LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS。
否則預設為 LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT。
在短邊凹口區域中顯示內容
如果應用程式以 SDK 35 為目標版本,且在 Android 15 裝置上執行,系統會將
LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES解讀為
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS (非浮動視窗)。
使用 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 時,無論系統資訊列是否隱藏或顯示,內容都會在直向和橫向模式下延伸至螢幕短邊的凹口區域。使用這個模式時,請務必確認重要內容不會與凹口區域重疊。
下圖是直向裝置的 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 範例:
下圖為橫向裝置的 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 範例:

無論視窗是否隱藏系統資訊列,在此模式下,視窗都會在直向和橫向模式中,延伸至螢幕短邊的凹口下方。
角落的凹口會視為位於短邊:
永不在螢幕凹口區域中算繪內容
如果應用程式以 SDK 35 為目標版本,且在 Android 15 裝置上執行,系統會將
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER解讀為
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS (非浮動視窗)。
使用 LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER 時,視窗一律不得與凹口區域重疊。
以下是直向模式的 LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER 範例:
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER。以下是橫向模式的 LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER 範例:
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER」範例。
螢幕凹口支援最佳做法
處理螢幕凹口時,請考量下列事項:
- 請注意使用者介面重要元素的放置位置。請勿讓凹口區域遮住任何重要文字、控制項或其他資訊。
- 請勿將需要精細觸控辨識的互動元素放置或延伸至剪裁區域。螢幕凹口區域的觸控敏感度可能較低。
請盡可能使用
WindowInsetsCompat擷取狀態列高度,並判斷要套用至內容的適當邊框間距。請避免將狀態列高度硬式編碼,否則可能會導致內容重疊或遭到截斷。
圖 7. 使用 WindowInsetsCompat避免內容重疊或遭到截斷。使用
View.getLocationInWindow()判斷應用程式使用的視窗空間大小。請勿假設應用程式可完整占用整個視窗,也不要使用View.getLocationOnScreen()。如果應用程式需要進入和退出沉浸模式,請使用
always、shortEdges或never螢幕凹口模式。預設的凹口行為可能會導致應用程式內容在系統資訊列存在時,於凹口區域中轉譯,但不會在沉浸模式下發生。這會導致內容在轉場期間上下移動,如下列範例所示。
圖 8. 在轉場期間,內容會上下移動,如圖所示。 在沉浸模式中,請小心使用視窗與螢幕座標,因為應用程式加上黑邊時不會使用整個螢幕。由於有上下黑邊,螢幕原點的座標與視窗原點的座標不同。您可以使用
getLocationOnScreen(),視需要將螢幕座標轉換為檢視區塊的座標。下圖顯示內容加上上下黑邊時,座標的差異:
圖 9. 內容加上上下黑邊時的視窗與螢幕座標。 處理
MotionEvent時,請使用MotionEvent.getX()和MotionEvent.getY(),避免發生類似的座標問題。請勿使用MotionEvent.getRawX()或MotionEvent.getRawY()。
測試內容的算繪方式
測試應用程式的所有畫面和體驗。盡可能在不同類型的凹口裝置上測試。如果沒有具備凹口的裝置,您可以在搭載 Android 9 以上版本的任何裝置或模擬器上,模擬常見的凹口設定,方法如下:
- 啟用「開發人員選項」。
- 在「開發人員選項」畫面中,向下捲動至「繪圖」部分,然後選取「模擬有凹口的螢幕」。
選取凹口類型。
圖 10. 開發人員選項,可測試內容的轉譯方式。
其他資源
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT