Mithilfe von WindowInsetsCompat
kann Ihre App die Bildschirmtastatur (auch IME genannt) abfragen und steuern, ähnlich wie sie mit den Systemleisten interagiert. Ihre App kann auch WindowInsetsAnimationCompat
verwenden, um nahtlose Übergänge zu erstellen, wenn die Softwaretastatur geöffnet oder geschlossen wird.
Voraussetzungen
Bevor Sie die Steuerung und Animation für die Softwaretastatur einrichten, konfigurieren Sie Ihre App für die Edge-to-Edge-Anzeige. Dadurch kann es Systemfenstereinsätze wie die Systemleisten und die Bildschirmtastatur verarbeiten.
Sichtbarkeit der Tastatursoftware prüfen
Mit WindowInsets
können Sie prüfen, ob die Softwaretastatur sichtbar ist.
Kotlin
val insets = ViewCompat.getRootWindowInsets(view) ?: return val imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()) val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
Java
WindowInsetsCompat insets = ViewCompat.getRootWindowInsets(view); boolean imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()); int imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
Alternativ können Sie ViewCompat.setOnApplyWindowInsetsListener
verwenden, um Änderungen an der Sichtbarkeit der Softwaretastatur zu beobachten.
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(view) { _, insets -> val imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()) val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom insets }
Java
ViewCompat.setOnApplyWindowInsetsListener(view, (v, insets) -> { boolean imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()); int imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom; return insets; });
Animation mit der Softwaretastatur synchronisieren
Wenn ein Nutzer auf ein Texteingabefeld tippt, wird die Tastatur vom unteren Bildschirmrand eingeblendet, wie im folgenden Beispiel zu sehen ist:
Das Beispiel mit der Bezeichnung „Nicht synchronisiert“ in Abbildung 2 zeigt das Standardverhalten in Android 10 (API-Level 29), bei dem das Textfeld und der Inhalt der App einrasten, anstatt sich mit der Animation der Tastatur zu synchronisieren. Dieses Verhalten kann visuell störend sein.
In Android 11 (API‑Level 30) und höher können Sie
WindowInsetsAnimationCompat
verwenden, um den Übergang der App mit dem Ein- und Ausblenden der Tastatur am unteren Bildschirmrand zu synchronisieren. Das sieht flüssiger aus, wie im Beispiel mit der Bezeichnung „Synchronisiert“ in Abbildung 2 zu sehen ist.
Konfigurieren Sie WindowInsetsAnimationCompat.Callback
so, dass sie mit der Tastaturanimation synchronisiert wird.
Kotlin
ViewCompat.setWindowInsetsAnimationCallback( view, object : WindowInsetsAnimationCompat.Callback(DISPATCH_MODE_STOP) { // Override methods. } )
Java
ViewCompat.setWindowInsetsAnimationCallback( view, new WindowInsetsAnimationCompat.Callback( WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_STOP ) { // Override methods. });
In WindowInsetsAnimationCompat.Callback
gibt es mehrere Methoden, die überschrieben werden können, nämlich onPrepare()
, onStart()
, onProgress()
und onEnd()
.
Rufen Sie zuerst onPrepare()
auf, bevor Sie Änderungen am Layout vornehmen.
onPrepare
wird aufgerufen, wenn eine Insets-Animation beginnt und bevor die Ansichten aufgrund einer Animation neu angeordnet werden. Damit können Sie den Startstatus speichern, in diesem Fall die untere Koordinate der Ansicht.

onPrepare()
verwenden, um den Startstatus aufzuzeichnen.
Das folgende Snippet zeigt ein Beispiel für einen Aufruf von onPrepare
:
Kotlin
var startBottom = 0f override fun onPrepare( animation: WindowInsetsAnimationCompat ) { startBottom = view.bottom.toFloat() }
Java
float startBottom; @Override public void onPrepare( @NonNull WindowInsetsAnimationCompat animation ) { startBottom = view.getBottom(); }
onStart
wird aufgerufen, wenn eine Insets-Animation beginnt. Damit können Sie alle Ansichtseigenschaften auf den Endstatus der Layoutänderungen festlegen. Wenn Sie für eine der Ansichten einen OnApplyWindowInsetsListener
-Callback festgelegt haben, wird er bereits an dieser Stelle aufgerufen. Jetzt ist ein guter Zeitpunkt, um den Endstatus der Ansichtseigenschaften zu speichern.

onStart()
verwenden, um den Endstatus aufzuzeichnen.
Das folgende Snippet zeigt ein Beispiel für einen Aufruf von onStart
:
Kotlin
var endBottom = 0f override fun onStart( animation: WindowInsetsAnimationCompat, bounds: WindowInsetsAnimationCompat.BoundsCompat ): WindowInsetsAnimationCompat.BoundsCompat { // Record the position of the view after the IME transition. endBottom = view.bottom.toFloat() return bounds }
Java
float endBottom; @NonNull @Override public WindowInsetsAnimationCompat.BoundsCompat onStart( @NonNull WindowInsetsAnimationCompat animation, @NonNull WindowInsetsAnimationCompat.BoundsCompat bounds ) { endBottom = view.getBottom(); return bounds; }
onProgress
wird aufgerufen, wenn sich die Insets im Rahmen einer Animation ändern. Sie können die Methode also überschreiben und bei jedem Frame während der Tastaturanimation benachrichtigt werden. Aktualisieren Sie die Ansichtseigenschaften so, dass die Ansicht synchron mit der Tastatur animiert wird.
Alle Layoutänderungen sind jetzt abgeschlossen. Wenn Sie beispielsweise View.translationY
verwenden, um die Ansicht zu verschieben, nimmt der Wert bei jedem Aufruf dieser Methode allmählich ab und erreicht schließlich 0
für die ursprüngliche Layoutposition.
onProgress()
, um die Animationen zu synchronisieren.
Das folgende Snippet zeigt ein Beispiel für einen Aufruf von onProgress
:
Kotlin
override fun onProgress( insets: WindowInsetsCompat, runningAnimations: MutableList<WindowInsetsAnimationCompat> ): WindowInsetsCompat { // Find an IME animation. val imeAnimation = runningAnimations.find { it.typeMask and WindowInsetsCompat.Type.ime() != 0 } ?: return insets // Offset the view based on the interpolated fraction of the IME animation. view.translationY = (startBottom - endBottom) * (1 - imeAnimation.interpolatedFraction) return insets }
Java
@NonNull @Override public WindowInsetsCompat onProgress( @NonNull WindowInsetsCompat insets, @NonNull List<WindowInsetsAnimationCompat> runningAnimations ) { // Find an IME animation. WindowInsetsAnimationCompat imeAnimation = null; for (WindowInsetsAnimationCompat animation : runningAnimations) { if ((animation.getTypeMask() & WindowInsetsCompat.Type.ime()) != 0) { imeAnimation = animation; break; } } if (imeAnimation != null) { // Offset the view based on the interpolated fraction of the IME animation. view.setTranslationY((startBottom - endBottom) * (1 - imeAnimation.getInterpolatedFraction())); } return insets; }
Optional können Sie onEnd
überschreiben. Diese Methode wird nach Abschluss der Animation aufgerufen. Jetzt ist ein guter Zeitpunkt, um temporäre Änderungen zu entfernen.
Zusätzliche Ressourcen
- WindowInsetsAnimation auf GitHub.