1. Einführung
Unter Android 10 oder höher werden Navigationsgesten als neuer Modus unterstützt. So kann Ihre App den gesamten Bildschirm nutzen und ein noch intensiveres Anzeigeerlebnis bieten. Wenn der Nutzer vom unteren Displayrand nach oben wischt, wird er zum Android-Startbildschirm weitergeleitet. Wenn der Nutzer vom linken oder rechten Rand nach innen wischt, wird der vorherige Bildschirm angezeigt.
Mit diesen beiden Gesten kann Ihre App den unteren Bereich des Displays nutzen. Wenn Ihre App jedoch Gesten verwendet oder Steuerelemente in den Bereichen für Systemgesten hat, kann es zu Konflikten mit systemweiten Gesten kommen.
In diesem Codelab erfahren Sie, wie Sie Insets verwenden, um Konflikte mit Gesten zu vermeiden. Außerdem soll in diesem Codelab gezeigt werden, wie Sie die Gesture Exclusion API für Steuerelemente wie Ziehpunkte verwenden, die sich in den Gestenzonen befinden müssen.
Lerninhalte
- Inset-Listener für Ansichten verwenden
- Gesture Exclusion API verwenden
- Verhalten des immersiven Modus bei aktiven Gesten
In diesem Codelab erfahren Sie, wie Sie Ihre App mit Systemgesten kompatibel machen. Irrelevante Konzepte und Codeblöcke werden nicht beachtet und können einfach kopiert und eingefügt werden.
Umfang
Der Universal Android Music Player (UAMP) ist eine Beispiel-Musikplayer-App für Android, die in Kotlin geschrieben wurde. Sie richten UAMP für die Bedienung über Gesten ein.
- Steuerelemente mit Insets von Gestenbereichen entfernen
- Mit der Gesture Exclusion API die Zurück-Geste für Steuerelemente deaktivieren, die in Konflikt stehen
- Mit Ihren Builds Verhaltensänderungen im Immersivmodus mit der Gestensteuerung untersuchen
Voraussetzungen
- Ein Gerät oder Emulator mit Android 10 oder höher
- Android Studio
2. App-Übersicht
Der Universal Android Music Player (UAMP) ist eine Beispiel-App für einen Musikplayer für Android, die in Kotlin geschrieben wurde. Es unterstützt Funktionen wie die Hintergrundwiedergabe, die Verarbeitung des Audiofokus, die Assistant-Integration und mehrere Plattformen wie Wear, TV und Auto.
|
|
|
Abbildung 1: Ein Ablauf in UAMP
UAMP lädt einen Musikkatalog von einem Remote-Server und ermöglicht es dem Nutzer, die Alben und Titel zu durchsuchen. Der Nutzer tippt auf einen Song und er wird über verbundene Lautsprecher oder Kopfhörer wiedergegeben. Die App ist nicht für die Verwendung mit Systemgesten konzipiert. Wenn Sie UAMP auf einem Gerät mit Android 10 oder höher ausführen, treten daher anfangs einige Probleme auf.
3. Einrichten
Wenn Sie die Beispielanwendung herunterladen möchten, klonen Sie das Repository von GitHub und wechseln Sie zum Zweig starter:
$ git clone https://github.com/googlecodelabs/android-gestural-navigation/
Alternativ können Sie das Repository als ZIP-Datei herunterladen, entzippen und in Android Studio öffnen.
Gehen Sie folgendermaßen vor:
- Öffnen Sie die App in Android Studio und erstellen Sie sie.
- Erstellen Sie ein neues virtuelles Gerät und wählen Sie API-Level 29 aus. Alternativ können Sie ein echtes Gerät mit API-Level 29 oder höher anschließen.
- Führen Sie die App aus. In der Liste, die angezeigt wird, werden die Songs unter den Optionen Empfohlen und Alben gruppiert.
- Klicke auf Empfohlen und wähle einen Song aus der Liste aus.
- Die App beginnt mit der Wiedergabe des Songs.
Bedienung über Gesten aktivieren
Wenn Sie eine neue Emulatorinstanz mit API-Level 29 ausführen, ist die Gestensteuerung möglicherweise nicht standardmäßig aktiviert. Wenn Sie die Bedienung über Gesten aktivieren möchten, wählen Sie Systemeinstellungen > System > Systemsteuerung > Bedienung über Gesten aus.
App mit der Bedienung über Gesten ausführen
Wenn Sie die App mit aktivierter Bewegungssteuerung ausführen und die Wiedergabe eines Songs starten, befinden sich die Player-Steuerelemente möglicherweise sehr nah an den Bereichen für die Startbildschirm- und Zurück-Gesten.
4. Edge-to-Edge-Anzeige
Was bedeutet „Edge-to-Edge“?
Apps, die unter Android 10 oder höher ausgeführt werden, können unabhängig davon, ob für die Navigation Gesten oder Schaltflächen aktiviert sind, auf dem gesamten Bildschirm angezeigt werden. Damit Ihre Apps ein Edge-to-Edge-Erlebnis bieten, müssen sie hinter der transparenten Navigations- und Statusleiste gerendert werden.
Hinter der Navigationsleiste zeichnen
Damit in Ihrer App Inhalte unter der Navigationsleiste gerendert werden können, müssen Sie zuerst den Hintergrund der Navigationsleiste transparent machen. Dann müssen Sie die Statusleiste transparent machen. So kann Ihre App über die gesamte Höhe des Bildschirms angezeigt werden.
So ändern Sie die Farbe der Navigationsleiste und der Statusleiste:
- Navigationsleiste:Öffnen Sie
res/values-29/styles.xmlund legen Sie fürnavigationBarColorden Wertcolor/transparentfest. - Statusleiste:Setzen Sie
statusBarColoraufcolor/transparent.
Sehen Sie sich das folgende Codebeispiel für res/values-29/styles.xml an:
<!-- change navigation bar color -->
<item name="android:navigationBarColor">
@android:color/transparent
</item>
<!-- change status bar color -->
<item name="android:statusBarColor">
@android:color/transparent
</item>
Sichtbarkeits-Flags für die System-UI
Außerdem müssen Sie die Sichtbarkeits-Flags der System-UI festlegen, damit das System die App unter den Systemleisten anordnet. Mit den systemUiVisibility-APIs in der Klasse View lassen sich verschiedene Flags festlegen. Führen Sie diese Schritte aus:
- Öffnen Sie die Klasse
MainActivity.ktund suchen Sie die MethodeonCreate(). Rufen Sie eine Instanz vonfragmentContainerab. - Setzen Sie Folgendes auf
content.systemUiVisibility:
View.SYSTEM_UI_FLAG_LAYOUT_STABLEView.SYSTEM_UI_FLAG_LAYOUT_FULLSCREENView.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
Sehen Sie sich das folgende Codebeispiel für MainActivity.kt an:
val content: FrameLayout = findViewById(R.id.fragmentContainer)
content.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
Wenn Sie diese Flags zusammen festlegen, teilen Sie dem System mit, dass Ihre App im Vollbildmodus angezeigt werden soll, als wären die Navigations- und Statusleisten nicht vorhanden. Führen Sie diese Schritte aus:
- Starte die App und wähle einen Titel aus, um zum Player-Bildschirm zu gelangen.
- Prüfe, ob die Player-Steuerelemente unter der Navigationsleiste angezeigt werden und daher schwer zugänglich sind:
|
|
- Gehen Sie zu den Systemeinstellungen, wechseln Sie zurück zum Navigationsmodus mit drei Schaltflächen und kehren Sie zur App zurück.
- Prüfen Sie, ob die Steuerelemente mit der Navigationsleiste mit drei Schaltflächen noch schwieriger zu verwenden sind: Das
SeekBarist hinter der Navigationsleiste verborgen und Wiedergabe/Pause wird größtenteils von der Navigationsleiste verdeckt. - Probieren Sie ein bisschen herum. Kehren Sie anschließend zu den Systemeinstellungen zurück und stellen Sie wieder auf „Bedienung über Gesten“ um:

Die App wird jetzt randlos dargestellt, es gibt aber Probleme mit der Nutzerfreundlichkeit und App-Steuerelemente, die sich überschneiden und in Konflikt stehen. Diese Probleme müssen behoben werden.
5. Einsätze
Mit WindowInsets wird der App mitgeteilt, wo die System-UI über Ihren Inhalten angezeigt wird und in welchen Bereichen des Bildschirms Systemgesten Vorrang vor In-App-Gesten haben. Insets werden in Jetpack durch die Klassen WindowInsets und WindowInsetsCompat dargestellt. Wir empfehlen dringend, WindowInsetsCompat zu verwenden, um ein einheitliches Verhalten auf allen API-Ebenen zu erzielen.
System-Insets und obligatorische System-Insets
Die folgenden Inset-APIs sind die am häufigsten verwendeten Inset-Typen:
- System-Window-Insets:Sie geben an, wo die System-UI über Ihrer App angezeigt wird. Wir erläutern, wie Sie System-Insets verwenden können, um Steuerelemente von den Systemleisten zu entfernen.
- System-Gesten-Insets:Sie geben alle Gestenbereiche zurück. In diesen Regionen können In-App-Wischsteuerungen versehentlich Systemgesten auslösen.
- Obligatorische Gesten-Insets:Sie sind eine Teilmenge der Systemgesten-Insets und können nicht überschrieben werden. Sie zeigen die Bereiche des Bildschirms an, in denen das Verhalten der System-Gesten immer Vorrang vor In-App-Gesten hat.
App-Steuerelemente mit Insets verschieben
Nachdem Sie nun mehr über Inset-APIs wissen, können Sie die App-Steuerelemente korrigieren. Gehen Sie dazu so vor:
- Rufen Sie eine Instanz von
playerLayoutaus derview-Objektinstanz ab. - Fügen Sie der
playerVieweinOnApplyWindowInsetsListenerhinzu. - Ansicht vom Gestenbereich entfernen: Ermitteln Sie den System-Inset-Wert für den unteren Rand und erhöhen Sie den Padding-Wert der Ansicht um diesen Betrag. Um das Padding der Ansicht entsprechend zu aktualisieren, addieren Sie zum [Wert für das untere Padding der App] den [Wert für den unteren Inset-Wert des Systems].
Sehen Sie sich das folgende Codebeispiel für NowPlayingFragment.kt an:
playerView = view.findViewById(R.id.playerLayout)
playerView.setOnApplyWindowInsetsListener { view, insets ->
view.updatePadding(
bottom = insets.systemWindowInsetBottom + view.paddingBottom
)
insets
}
- Starte die App und wähle einen Titel aus. Es scheint sich nichts an den Player-Steuerelementen zu ändern. Wenn Sie einen Haltepunkt hinzufügen und die App im Debug-Modus ausführen, sehen Sie, dass der Listener nicht aufgerufen wird.
- Um das Problem zu beheben, wechseln Sie zu
FragmentContainerView. Dort wird das Problem automatisch behoben. Öffnen Sieactivity_main.xmlund ändern SieFrameLayoutinFragmentContainerView.
Sehen Sie sich das folgende Codebeispiel für activity_main.xml an:
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragmentContainer"
tools:context="com.example.android.uamp.MainActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
- Führen Sie die App noch einmal aus und rufen Sie den Playerbildschirm auf. Die unteren Player-Steuerelemente werden vom unteren Bereich für Touch-Gesten weg verschoben.
Die App-Steuerelemente funktionieren jetzt mit der Gestensteuerung, aber sie bewegen sich mehr als erwartet. Sie müssen dieses Problem beheben.
Aktuelles Padding und aktuelle Ränder beibehalten
Wenn Sie zu anderen Apps wechseln oder zum Startbildschirm gehen und zur App zurückkehren, ohne sie zu schließen, werden die Player-Steuerelemente jedes Mal nach oben verschoben.
Das liegt daran, dass die App jedes Mal, wenn die Aktivität beginnt, requestApplyInsets() auslöst. Auch ohne diesen Aufruf kann WindowInsets jederzeit während des Lebenszyklus einer Ansicht mehrmals gesendet werden.
Der aktuelle InsetListener auf dem playerView funktioniert beim ersten Mal einwandfrei, wenn Sie den Wert für „inset bottom“ zum Wert für das untere Padding der App hinzufügen, der in activity_main.xml deklariert ist. Bei nachfolgenden Aufrufen wird der Wert für „inset bottom“ jedoch weiterhin zum bereits aktualisierten unteren Padding der Ansicht hinzugefügt.
So beheben Sie das Problem:
- Notieren Sie den ursprünglichen Wert für den Ansichtsabstand. Erstellen Sie einen neuen „val“ und speichern Sie den ursprünglichen Wert für das Ansichtspadding von
playerViewdirekt vor dem Listener-Code.
Sehen Sie sich das folgende Codebeispiel für NowPlayingFragment.kt an:
val initialPadding = playerView.paddingBottom
- Mit diesem Startwert können Sie das untere Padding der Ansicht aktualisieren, sodass Sie den aktuellen Wert für das untere Padding der App nicht verwenden müssen.
Sehen Sie sich das folgende Codebeispiel für NowPlayingFragment.kt an:
playerView.setOnApplyWindowInsetsListener { view, insets ->
view.updatePadding(bottom = insets.systemWindowInsetBottom + initialPadding)
insets
}
- Führen Sie die App noch einmal aus. Zwischen Apps wechseln und zum Startbildschirm zurückkehren Wenn Sie die App zurückgeben, befinden sich die Player-Steuerelemente direkt über dem Bereich für die Touch-Gesten.
App-Steuerelemente neu gestalten
Die Fortschrittsanzeige des Players befindet sich zu nah am unteren Bereich für Gesten. Das bedeutet, dass Nutzer versehentlich die Startbildschirm-Geste auslösen können, wenn sie horizontal wischen. Wenn Sie das Padding noch weiter erhöhen, kann das Problem behoben werden, aber der Player wird möglicherweise höher als gewünscht positioniert.
Mit Insets lassen sich Konflikte mit Gesten beheben. Manchmal können Sie sie aber auch durch kleine Designänderungen ganz vermeiden. So gestalten Sie die Player-Steuerelemente neu, um Konflikte mit Gesten zu vermeiden:
- Öffnen Sie
fragment_nowplaying.xml. Wechseln Sie zur Designansicht und wählen Sie ganz untenSeekBaraus:

- Wechseln Sie zur Codeansicht.
- Wenn Sie die
SeekBaran den Anfang derplayerLayoutverschieben möchten, ändern Sielayout_constraintTop_toBottomOfder SeekBar inparent. - Wenn Sie andere Elemente in
playerViewan den unteren Rand vonSeekBaranpassen möchten, ändern Sielayout_constraintTop_toTopOfvon „parent“ zu@+id/seekBarfürmedia_button,titleundposition.
Sehen Sie sich das folgende Codebeispiel für fragment_nowplaying.xml an:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:layout_gravity="bottom"
android:background="@drawable/media_overlay_background"
android:id="@+id/playerLayout">
<ImageButton
android:id="@+id/media_button"
android:layout_width="@dimen/exo_media_button_width"
android:layout_height="@dimen/exo_media_button_height"
android:background="?attr/selectableItemBackground"
android:scaleType="centerInside"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/seekBar"
app:srcCompat="@drawable/ic_play_arrow_black_24dp"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginStart="@dimen/text_margin"
android:layout_marginEnd="@dimen/text_margin"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Uamp.Title"
app:layout_constraintTop_toTopOf="@+id/seekBar"
app:layout_constraintLeft_toRightOf="@id/media_button"
app:layout_constraintRight_toLeftOf="@id/position"
tools:text="Song Title" />
<TextView
android:id="@+id/subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/text_margin"
android:layout_marginEnd="@dimen/text_margin"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Uamp.Subtitle"
app:layout_constraintTop_toBottomOf="@+id/title"
app:layout_constraintLeft_toRightOf="@id/media_button"
app:layout_constraintRight_toLeftOf="@id/position"
tools:text="Artist" />
<TextView
android:id="@+id/position"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginStart="@dimen/text_margin"
android:layout_marginEnd="@dimen/text_margin"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Uamp.Title"
app:layout_constraintTop_toTopOf="@+id/seekBar"
app:layout_constraintRight_toRightOf="parent"
tools:text="0:00" />
<TextView
android:id="@+id/duration"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/text_margin"
android:layout_marginEnd="@dimen/text_margin"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Uamp.Subtitle"
app:layout_constraintTop_toBottomOf="@id/position"
app:layout_constraintRight_toRightOf="parent"
tools:text="0:00" />
<SeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- Führen Sie die App aus und interagieren Sie mit dem Player und der Suchleiste.
Diese minimalen Designänderungen verbessern die App erheblich.
6. Gesture Exclusion API
Die Player-Steuerelemente für Gestenkonflikte im Bereich für Home-Gesten wurden korrigiert. Der Bereich für die Zurück-Geste kann auch zu Konflikten mit den App-Steuerelementen führen. Der folgende Screenshot zeigt, dass sich die Suchleiste des Players derzeit sowohl im Bereich für die rechte als auch für die linke Zurück-Geste befindet:

SeekBar verarbeitet automatisch Konflikte mit Gesten. Möglicherweise müssen Sie jedoch andere UI-Komponenten verwenden, die zu Konflikten mit Gesten führen. In diesen Fällen können Sie mit Gesture Exclusion API die Zurück-Geste teilweise deaktivieren.
Gesture Exclusion API verwenden
Rufen Sie setSystemGestureExclusionRects() für Ihre Ansicht mit einer Liste von rect-Objekten auf, um eine Ausschlusszone für Gesten zu erstellen. Diese rect-Objekte entsprechen den Koordinaten der ausgeschlossenen rechteckigen Bereiche. Dieser Aufruf muss in den Methoden onLayout() oder onDraw() der Ansicht erfolgen. Führen Sie zu diesem Zweck die folgenden Schritte aus:
- Erstellen Sie ein neues Paket mit dem Namen
view. - Um diese API aufzurufen, erstellen Sie eine neue Klasse mit dem Namen
MySeekBarund erweitern SieAppCompatSeekBar.
Sehen Sie sich das folgende Codebeispiel für MySeekBar.kt an:
class MySeekBar @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = android.R.attr.seekBarStyle
) : androidx.appcompat.widget.AppCompatSeekBar(context, attrs, defStyle) {
}
- Erstellen Sie eine neue Methode mit dem Namen
updateGestureExclusion().
Sehen Sie sich das folgende Codebeispiel für MySeekBar.kt an:
private fun updateGestureExclusion() {
}
- Fügen Sie eine Prüfung hinzu, um diesen Aufruf bei API-Level 28 oder niedriger zu überspringen.
Sehen Sie sich das folgende Codebeispiel für MySeekBar.kt an:
private fun updateGestureExclusion() {
// Skip this call if we're not running on Android 10+
if (Build.VERSION.SDK_INT < 29) return
}
- Da die Gesture Exclusion API ein Limit von 200 dp hat, sollte nur der Daumen der Seekbar ausgeschlossen werden. Rufen Sie eine Kopie der Grenzen der Suchleiste ab und fügen Sie jedes Objekt einer veränderlichen Liste hinzu.
Sehen Sie sich das folgende Codebeispiel für MySeekBar.kt an:
private val gestureExclusionRects = mutableListOf<Rect>()
private fun updateGestureExclusion() {
// Skip this call if we're not running on Android 10+
if (Build.VERSION.SDK_INT < 29) return
thumb?.also { t ->
gestureExclusionRects += t.copyBounds()
}
}
- Rufen Sie
systemGestureExclusionRects()mit den von Ihnen erstelltengestureExclusionRects-Listen auf.
Sehen Sie sich das folgende Codebeispiel für MySeekBar.kt an:
private val gestureExclusionRects = mutableListOf<Rect>()
private fun updateGestureExclusion() {
// Skip this call if we're not running on Android 10+
if (Build.VERSION.SDK_INT < 29) return
thumb?.also { t ->
gestureExclusionRects += t.copyBounds()
}
// Finally pass our updated list of rectangles to the system
systemGestureExclusionRects = gestureExclusionRects
}
- Rufen Sie die Methode
updateGestureExclusion()überonDraw()oderonLayout()auf. Überschreiben SieonDraw()und fügen Sie einen Aufruf vonupdateGestureExclusionhinzu.
Sehen Sie sich das folgende Codebeispiel für MySeekBar.kt an:
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
updateGestureExclusion()
}
- Sie müssen die
SeekBar-Referenzen aktualisieren. Öffnen Siefragment_nowplaying.xml, um zu beginnen. - Ändern Sie
SeekBarzucom.example.android.uamp.view.MySeekBar.
Sehen Sie sich das folgende Codebeispiel für fragment_nowplaying.xml an:
<com.example.android.uamp.view.MySeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent" />
- Wenn Sie die
SeekBar-Verweise inNowPlayingFragment.ktaktualisieren möchten, öffnen SieNowPlayingFragment.ktund ändern Sie den Typ vonpositionSeekBarinMySeekBar. Um den Variablentyp anzupassen, ändern Sie dieSeekBar-Generics für denfindViewById-Aufruf inMySeekBar.
Sehen Sie sich das folgende Codebeispiel für NowPlayingFragment.kt an:
val positionSeekBar: MySeekBar = view.findViewById<MySeekBar>(
R.id.seekBar
).apply { progress = 0 }
- Führen Sie die App aus und interagieren Sie mit
SeekBar. Wenn weiterhin Konflikte mit Gesten auftreten, können Sie die Daumenbegrenzungen inMySeekBaranpassen. Achten Sie darauf, keine unnötig großen Ausschlussbereiche für Gesten zu erstellen, da dies andere potenzielle Aufrufe für den Ausschluss von Gesten einschränkt und zu einem inkonsistenten Verhalten für den Nutzer führt.
7. Glückwunsch
Glückwunsch! Sie haben gelernt, wie Sie Konflikte mit Systemgesten vermeiden und lösen können.
Sie haben Ihre App im Vollbildmodus verwendet, als Sie die Edge-to-Edge-Funktion erweitert und Insets verwendet haben, um App-Steuerelemente von Gestenzonen zu entfernen. Außerdem haben Sie gelernt, wie Sie die System-Touchgeste „Zurück“ für App-Steuerelemente deaktivieren.
Sie kennen jetzt die wichtigsten Schritte, die erforderlich sind, damit Ihre Apps mit Systemgesten funktionieren.
Zusätzliche Materialien
- WindowInsets – Listener für Layouts
- Bedienung über Gesten: Edge-to-Edge
- Bedienung über Gesten: Visuelle Überschneidungen behandeln
- Bedienung über Gesten: Konflikte bei Gesten behandeln
- Kompatibilität mit der Bedienung über Gesten sicherstellen




