Su alcuni dispositivi, un taglio del display è un'area che si estende fino alla superficie del display. Offre un'esperienza edge-to-edge senza compromettere i sensori importanti sulla parte anteriore del dispositivo.
Android supporta i ritagli del display sui dispositivi con Android 9 (livello API 28) e versioni successive. Tuttavia, i produttori possono supportare i ritagli del display anche sui dispositivi con Android 8.1 o versioni precedenti.
Questo documento descrive come implementare il supporto per i dispositivi con sagome, incluso come utilizzare l'area di ritaglio, ovvero il rettangolo da bordo a bordo sulla superficie del display che contiene il ritaglio.
Scegliere la modalità di gestione delle aree di ritaglio nell'app
Se non vuoi che i tuoi contenuti si sovrappongano a un'area di ritaglio, è generalmente sufficiente assicurarsi che i contenuti non si sovrappongano alla barra di stato e alla barra di navigazione. Se stai eseguendo il rendering nell'area di ritaglio, utilizza WindowInsetsCompat.getDisplayCutout()
per recuperare un oggetto DisplayCutout
che contiene i riquadri sicuri e il riquadro di delimitazione per ogni ritaglio. Queste API consentono
di verificare se i contenuti si sovrappongono al ritaglio per riposizionarlo, se necessario.
Puoi anche determinare se i contenuti sono posizionati dietro l'area di ritaglio. L'attributo di layout finestra layoutInDisplayCutoutMode
controlla il modo in cui i contenuti vengono disegnati nell'area di ritaglio.
Puoi impostare layoutInDisplayCutoutMode
su uno dei seguenti valori:
LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
: i contenuti vengono visualizzati nell'area di ritaglio quando il ritaglio display è contenuto in una barra di sistema. In caso contrario, la finestra non si sovrappone al ritaglio display; ad esempio, i contenuti potrebbero apparire in formato letterbox quando visualizzati in modalità Orizzontale. Se la tua app ha come target l'SDK 35, questo viene interpretato comeALWAYS
per le finestre non floating.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
: i contenuti possono sempre estendersi nelle aree di ritaglio. Se la tua app ha come target SDK 35 ed è in esecuzione su un dispositivo Android 15, questa è l'unica modalità consentita per le finestre non mobile per garantire un display edge-to-edge.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
: i contenuti vengono visualizzati nell'area di ritaglio sia in modalità verticale che orizzontale. Non utilizzarlo per finestre mobili. Se la tua app ha come target l'SDK 35, questo viene interpretato comeALWAYS
per le finestre non floating.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
: i contenuti non vengono mai visualizzati nell'area di ritaglio. Se la tua app ha come target l'SDK 35, questo viene interpretato comeALWAYS
per le finestre non mobili.
Puoi impostare la modalità di ritaglio in modo programmatico o impostando uno
stile nella tua attività. L'esempio
seguente definisce uno stile per applicare l'attributo LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
all'attività.
<style name="ActivityTheme"> <item name="android:windowLayoutInDisplayCutoutMode"> shortEdges <!-- default, shortEdges, or never --> </item> </style>
Le seguenti sezioni descrivono in maggiore dettaglio le diverse modalità di ritaglio.
Comportamento predefinito
Se la tua app ha come target l'SDK 35 ed è in esecuzione su un dispositivo Android 15, il comportamento predefinito è LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
, mentre LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
viene interpretato come LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
per le finestre non mobili.
In caso contrario, LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
è l'impostazione predefinita.
Visualizza i contenuti in aree di ritaglio con bordi corti
Se la tua app ha come target l'SDK 35 ed è in esecuzione su un dispositivo Android 15,
LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
viene interpretato come
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
per le finestre non mobili.
Con LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
, i
contenuti si estendono nell'area di ritaglio sul bordo corto del display sia
in verticale che in orizzontale, a prescindere dal fatto che le barre di sistema siano nascoste o
visibili. Quando utilizzi questa modalità, assicurati che nessun contenuto importante si sovrapponga all'area di ritaglio.
L'immagine seguente è un esempio di LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
per un dispositivo in verticale:
Di seguito è riportato un esempio di LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
per un dispositivo in orizzontale:
In questa modalità, la finestra si estende sotto i ritagli sul bordo corto del display sia in verticale che in orizzontale, a prescindere dal fatto che la finestra nasconda le barre del sistema.
Un ritaglio nell'angolo viene considerato sul lato corto:
Non visualizzare mai i contenuti nell'area di ritaglio display
Se la tua app ha come target l'SDK 35 ed è in esecuzione su un dispositivo Android 15,
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
viene interpretato come
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
per le finestre non mobili.
Con LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
, la finestra non può mai
sovrapporsi con l'area di ritaglio.
Di seguito è riportato un esempio di LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
in verticale:
Di seguito è riportato un esempio di LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
in
modalità orizzontale:
Best practice per il supporto del ritaglio display
Quando lavori con ritagli del display, considera quanto segue:
- Fai attenzione al posizionamento di elementi critici dell'interfaccia utente. Fai in modo che l'area di ritaglio oscura testo, controlli o altre informazioni importanti.
- Non posizionare o estendere nell'area di ritaglio elementi interattivi che richiedono il riconoscimento del tocco. La sensibilità del tocco potrebbe essere più bassa nell'area di ritaglio.
Se possibile, utilizza
WindowInsetsCompat
per recuperare l'altezza della barra di stato e determinare la spaziatura interna appropriata da applicare ai contenuti. Evita di impostare come hardcoded l'altezza della barra di stato, poiché ciò può causare la sovrapposizione o il troncamento dei contenuti.Usa
View.getLocationInWindow()
per determinare la quantità di spazio delle finestre utilizzata dalla tua app. Non dare per scontato che l'app utilizzi l'intera finestra e non usareView.getLocationOnScreen()
.Usa le modalità di ritaglio
always
,shortEdges
onever
se la tua app deve passare dalla modalità immersiva alla modalità immersiva. Il comportamento di ritaglio predefinito può far sì che i contenuti della tua app vengano visualizzati nell'area di ritaglio mentre sono presenti le barre di sistema, ma non in modalità immersiva. In questo modo, i contenuti si spostano verso l'alto e verso il basso durante le transizioni, come mostrato nell'esempio seguente.In modalità immersiva, fai attenzione a utilizzare le coordinate della finestra rispetto allo schermo, poiché la tua app non utilizza l'intero schermo quando viene utilizzato il letterbox. Per via della letterbox, le coordinate dall'origine della schermata non corrispondono a quelle dell'origine della finestra. Se necessario, puoi trasformare le coordinate dello schermo nelle coordinate della vista utilizzando
getLocationOnScreen()
. La seguente immagine mostra le differenze di coordinate quando i contenuti vengono adattati al formato letterbox:Quando gestisci
MotionEvent
, utilizzaMotionEvent.getX()
eMotionEvent.getY()
per evitare problemi simili alle coordinate. Non utilizzareMotionEvent.getRawX()
oMotionEvent.getRawY()
.
Testare la modalità di rendering dei contenuti
Testa tutte le schermate e le esperienze della tua app. Se possibile, esegui il test su dispositivi con diversi tipi di ritagli. Se non hai un dispositivo con ritaglio, puoi simulare configurazioni di ritagli comuni su qualsiasi dispositivo o emulatore con Android 9 o versioni successive:
- Attiva le Opzioni sviluppatore.
- Nella schermata Opzioni sviluppatore, scorri verso il basso fino alla sezione Disegno e seleziona Simula un display con un ritaglio.
Seleziona il tipo di ritaglio.
Risorse aggiuntive
- 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