Eine Display-Aussparung ist bei einigen Geräten ein Bereich, der in die Displayfläche hineinragt. Sie ermöglicht eine randlose Umgebung und bietet gleichzeitig Platz für wichtige Sensoren an der Vorderseite des Geräts.
Android unterstützt Display-Aussparungen auf Geräten mit Android 9 (API-Level 28) und höher. Gerätehersteller können jedoch auch Display-Aussparungen auf Geräten mit Android 8.1 oder niedriger unterstützen.
In diesem Dokument wird beschrieben, wie Sie die Unterstützung für Geräte mit Aussparungen implementieren, einschließlich der Arbeit mit dem Aussparungsbereich, d. h. des randlosen Rechtecks auf der Displayoberfläche, das die Aussparung enthält.
Festlegen, wie die App mit Ausschnitten umgehen soll
Wenn Sie nicht möchten, dass sich Ihre Inhalte mit einem Aussparungsbereich überschneiden, sollten Sie darauf achten, dass sich der Inhalt nicht mit der Statusleiste und der Navigationsleiste überschneidet. Beim Rendern im Aussparungsbereich verwenden Sie WindowInsetsCompat.getDisplayCutout()
, um ein DisplayCutout
-Objekt abzurufen, das die sicheren Einfügungen und den Begrenzungsrahmen für jede Aussparung enthält. Mit diesen APIs kannst du prüfen, ob sich deine Inhalte mit der Aussparung überlappen, und die Position dann bei Bedarf neu positionieren.
Du kannst auch bestimmen, ob der Inhalt hinter dem Aussparungsbereich liegt. Mit dem Fenster-Layoutattribut layoutInDisplayCutoutMode
wird gesteuert, wie Ihre Inhalte im Aussparungsbereich gezeichnet werden.
Sie können für layoutInDisplayCutoutMode
einen der folgenden Werte festlegen:
LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
: Inhalt wird im Aussparungsbereich gerendert, wenn sich die Display-Aussparung in einer Systemleiste befindet. Andernfalls überlappt das Fenster nicht die Display-Aussparung. So kann es beispielsweise sein, dass Inhalte im Querformat mit Letterbox-Balken angezeigt werden. Wenn Ihre App auf SDK 35 ausgerichtet ist, wird dies bei nicht schwebenden Fenstern alsALWAYS
interpretiert.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
: Inhalte dürfen sich immer über die Aussparungen erstrecken. Wenn Ihre App auf SDK 35 ausgerichtet ist und auf einem Android 15-Gerät ausgeführt wird, ist dies der einzige zulässige Modus für nicht unverankerte Fenster, um eine randlose Anzeige zu gewährleisten.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
: Der Inhalt wird sowohl im Hoch- als auch im Querformat im Aussparungsbereich gerendert. Nicht für unverankerte Fenster verwenden. Wenn Ihre App auf SDK 35 ausgerichtet ist, wird dies bei nicht unverankerten Fenstern alsALWAYS
interpretiert.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
: Der Inhalt wird nie in den Aussparungsbereich gerendert. Wenn Ihre App auf SDK 35 ausgerichtet ist, wird dies bei nicht unverankerten Fenstern alsALWAYS
interpretiert.
Sie können den Ausschneidemodus entweder programmatisch oder durch Festlegen eines Stils in Ihrer Aktivität festlegen. Im folgenden Beispiel wird ein Stil definiert, mit dem das Attribut LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
auf die Aktivität angewendet wird.
<style name="ActivityTheme"> <item name="android:windowLayoutInDisplayCutoutMode"> shortEdges <!-- default, shortEdges, or never --> </item> </style>
In den folgenden Abschnitten werden die verschiedenen Aussparungsmodi ausführlicher beschrieben.
Standardverhalten
Wenn deine App auf SDK 35 ausgerichtet ist und auf einem Android 15-Gerät ausgeführt wird, ist LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
das Standardverhalten und LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
wird als LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
für nicht unverankerte Fenster interpretiert.
Andernfalls ist LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
die Standardeinstellung.
Inhalt in kurzen Aussparungsbereichen rendern
Wenn deine App auf SDK 35 ausgerichtet ist und auf einem Android 15-Gerät ausgeführt wird, wird LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
für nicht unverankerte Fenster als LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
interpretiert.
Mit LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
wird der Inhalt sowohl im Hoch- als auch im Querformat bis zum Aussparungsbereich am kurzen Displayrand ausgeweitet, unabhängig davon, ob die Systemleisten ausgeblendet oder sichtbar sind. Achten Sie bei diesem Modus darauf, dass sich keine wichtigen Inhalte mit der Aussparung überlappen.
Die folgende Abbildung zeigt ein Beispiel für LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
für ein Gerät im Hochformat:
Die folgende Abbildung zeigt ein Beispiel für LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
für ein Gerät im Querformat:
In diesem Modus wird das Fenster sowohl im Hoch- als auch im Querformat unter Aussparungen an der kurzen Seite des Bildschirms erweitert, unabhängig davon, ob die Systemleisten durch das Fenster ausgeblendet werden.
Eine Aussparung in der Ecke gilt als an der kurzen Seite:
Inhalte nie im Display-Aussparungsbereich rendern
Wenn deine App auf SDK 35 ausgerichtet ist und auf einem Android 15-Gerät ausgeführt wird, wird LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
für nicht unverankerte Fenster als LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
interpretiert.
Bei LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
darf sich das Fenster niemals mit dem Aussparungsbereich überschneiden.
Hier sehen Sie ein Beispiel für LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
im Hochformat:
Hier sehen Sie ein Beispiel für LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
im Querformat:
Best Practices für die Unterstützung von Display-Aussparungen
Beachten Sie bei der Arbeit mit Display-Aussparungen Folgendes:
- Achten Sie auf die Platzierung kritischer Elemente auf der Benutzeroberfläche. Achten Sie darauf, dass der Aussparungsbereich keinen wichtigen Text, keine Steuerelemente oder andere Informationen verdeckt.
- Platzieren oder erweitern Sie keine interaktiven Elemente, die eine Fein-Touch-Erkennung erfordern, im Aussparungsbereich. Die Berührungsempfindlichkeit ist im Aussparungsbereich möglicherweise niedriger.
Verwenden Sie nach Möglichkeit
WindowInsetsCompat
, um die Höhe der Statusleiste abzurufen und den geeigneten Abstand für Ihre Inhalte zu bestimmen. Vermeiden Sie eine Hartcodierung der Höhe der Statusleiste, da dies zu Überschneidungen oder abgeschnittenen Inhalten führen kann.Mit
View.getLocationInWindow()
kannst du feststellen, wie viel Fensterspeicherplatz deine App nutzt. Nicht davon ausgehen, dass die Anwendung das gesamte Fenster nutzt, und nichtView.getLocationOnScreen()
verwenden.Verwende die Ausblendungsmodi
always
,shortEdges
odernever
, wenn deine App in den immersiven Modus wechseln und wieder beenden muss. Das Standardverhalten für die Aussparung kann dazu führen, dass Inhalte in Ihrer App im Aussparungsbereich gerendert werden, wenn die Systembalken vorhanden sind, aber nicht im immersiven Modus. Dies führt dazu, dass sich der Inhalt während Übergängen nach oben und unten bewegt, wie im folgenden Beispiel gezeigt.Im immersiven Modus sollten Sie Fenster- und Bildschirmkoordinaten mit Bedacht verwenden, da Ihre App im Letterbox-Format nicht den gesamten Bildschirm verwendet. Aufgrund der Letterbox sind die Koordinaten des Bildschirmursprungs nicht mit den Koordinaten des Fensterursprungs identisch. Mit
getLocationOnScreen()
können Sie Bildschirmkoordinaten nach Bedarf in die Koordinaten der Ansicht umwandeln. Die folgende Abbildung zeigt, wie sich Koordinaten unterscheiden, wenn Inhalte mit Letterbox-Balken versehen werden:Verwenden Sie bei der Verarbeitung von
MotionEvent
MotionEvent.getX()
undMotionEvent.getY()
, um ähnliche Koordinatenprobleme zu vermeiden. Verwenden Sie nichtMotionEvent.getRawX()
oderMotionEvent.getRawY()
.
Testen, wie deine Inhalte gerendert werden
Testen Sie alle Bildschirme und Nutzererfahrungen Ihrer App. Teste es wenn möglich auf Geräten mit verschiedenen Aussparungen. Wenn Sie kein Gerät mit einer Aussparung haben, können Sie gängige Aussparungskonfigurationen auf jedem Gerät oder Emulator mit Android 9 oder höher simulieren. Gehen Sie dazu so vor:
- Aktivieren Sie Entwickleroptionen.
- Scrollen Sie auf dem Bildschirm Entwickleroptionen nach unten zum Abschnitt Zeichnung und wählen Sie Bildschirm mit Aussparung simulieren aus.
Wählen Sie die Art der Aussparung aus.
Zusätzliche Ressourcen
- 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