Mit WindowInsetsCompat
kann Ihre App die Bildschirmtastatur (auch IME genannt) ähnlich wie die Systemleisten abfragen und steuern. In Ihrer App kann auch das Symbol WindowInsetsAnimationCompat
verwendet werden, um nahtlose Übergänge beim Öffnen oder Schließen der Softwaretastatur zu ermöglichen.
Voraussetzungen
Bevor Sie die Steuerung und Animation für die Softwaretastatur einrichten, konfigurieren Sie Ihre App so, dass sie randlos angezeigt wird. So können Systemfenster-Einsätze wie die Systemleisten und die Bildschirmtastatur berücksichtigt werden.
Sichtbarkeit der Tastatursoftware prüfen
Mit WindowInsets
können Sie die Sichtbarkeit der Softwaretastatur prüfen.
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 Textfeld tippt, wird die Tastatur von unten auf dem Bildschirm eingeblendet, wie im folgenden Beispiel gezeigt:
Das Beispiel mit der Beschriftung „Nicht synchronisiert“ in Abbildung 2 zeigt das Standardverhalten in Android 10 (API-Ebene 29). Dabei werden das Textfeld und der Inhalt der App an ihre Position gebracht, anstatt sich mit der Tastaturanimation zu synchronisieren. Das kann optisch irritierend wirken.
Ab Android 11 (API-Level 30) kannst du
WindowInsetsAnimationCompat
verwenden, um den Übergang der App zu synchronisieren, wobei die Tastatur vom unteren Bildschirmrand nach oben und unten gleitet. Das sieht glatter aus, wie in Abbildung 2 im Beispiel mit der Beschriftung „Synchronisiert“ zu sehen ist.
Konfigurieren Sie WindowInsetsAnimationCompat.Callback
mit der Ansicht, die mit der Tastaturanimation synchronisiert werden soll.
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. });
Es gibt mehrere Methoden, die in WindowInsetsAnimationCompat.Callback
überschrieben werden können: onPrepare()
, onStart()
, onProgress()
und onEnd()
.
Rufen Sie zuerst onPrepare()
auf, bevor sich das Layout ändert.
onPrepare
wird aufgerufen, wenn eine Einblendungsanimation gestartet wird und bevor die Ansichten aufgrund einer Animation neu angeordnet werden. Sie können damit den Startstatus speichern, in diesem Fall die untere Koordinate der Ansicht.
Das folgende Snippet zeigt einen Beispielaufruf für 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 Einblendungsanimation beginnt. Sie können damit alle Ansichtseigenschaften auf den Endstatus der Layoutänderungen setzen. Wenn ein OnApplyWindowInsetsListener
-Callback auf eine der Ansichten festgelegt ist, wird er an diesem Punkt bereits aufgerufen. Jetzt ist ein guter Zeitpunkt, den Endstatus der Ansichtseigenschaften zu speichern.
Das folgende Snippet zeigt einen Beispielaufruf 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 Einzüge während der Ausführung einer Animation ändern. Sie können sie überschreiben und bei jedem Frame während der Tastaturanimation benachrichtigt werden. Aktualisieren Sie die Ansichtseigenschaften, damit 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
, die ursprüngliche Layoutposition.
Das folgende Snippet zeigt einen Beispielaufruf für 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. Dies ist ein guter Zeitpunkt, um alle temporären Änderungen zu entfernen.
Weitere Informationen
- WindowInsetsAnimation auf GitHub.