Avec WindowInsetsCompat
,
votre application peut interroger et contrôler le clavier à l'écran (également appelé
IME) semblable au
dont il interagit avec les barres système. Votre application peut également utiliser
WindowInsetsAnimationCompat
pour créer des transitions fluides lorsque le clavier virtuel est ouvert ou fermé.
Prérequis
Avant de configurer les commandes et l'animation pour le clavier virtuel, configurez votre application pour qu'elle s'affiche de bord à bord. Cela permet il gère les encarts de fenêtre système, tels que les barres système et le clavier à l'écran.
Vérifier la visibilité du logiciel du clavier
Utilisez WindowInsets
pour vérifier les logiciels
visibilité du clavier.
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;
Vous pouvez également utiliser
ViewCompat.setOnApplyWindowInsetsListener
pour observer les changements de visibilité du clavier virtuel.
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; });
Synchroniser l'animation avec le clavier virtuel
Lorsqu'un utilisateur appuie sur un champ de saisie de texte, le clavier se met en place en bas de l'écran, comme illustré dans l'exemple suivant:
<ph type="x-smartling-placeholder">L'exemple intitulé "Unsynchronized" la figure 2 illustre le comportement par défaut sous Android 10 (niveau d'API 29), dans lequel le champ de texte et le contenu de l'application au lieu de se synchroniser avec les Animation : un comportement qui peut être visuellement choquant.
Sur Android 11 (niveau d'API 30) ou version ultérieure, vous pouvez utiliser
WindowInsetsAnimationCompat
pour synchroniser la transition de l'application avec clavier en glissant de haut en bas à partir du bas de l'écran. Cela semble plus lisse, comme dans l'exemple intitulé "Synchronisé" comme illustré dans la figure 2.
Configurer
WindowInsetsAnimationCompat.Callback
avec l'affichage à synchroniser
avec l'animation du clavier.
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. });
Il existe plusieurs méthodes à remplacer dans WindowInsetsAnimationCompat.Callback
.
à savoir
onPrepare()
,
onStart()
,
onProgress()
et
onEnd()
Commencez par appeler onPrepare()
avant tout changement de mise en page.
onPrepare
est appelé au démarrage d'une animation d'encarts et avant les vues.
sont remis en place en raison d'une animation. Vous pouvez l'utiliser pour
enregistrer l'état de départ,
qui, dans ce cas, est la coordonnée
inférieure de la vue.
![Image montrant la coordonnée inférieure de l'état de départ de la vue racine.](https://developer.android.google.cn/static/images/guide/navigation/software-keyboard-3.png?authuser=9&hl=fr)
onPrepare()
pour
enregistrer l'état de départ.
L'extrait de code suivant présente un exemple d'appel à 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
est appelé au démarrage d'une animation d'encarts. Vous pouvez l'utiliser pour définir
les propriétés de la vue à l'état final
des modifications de la mise en page. Si vous disposez d'un
OnApplyWindowInsetsListener
défini sur l'une des vues, il est déjà
appelé à ce stade. C'est le bon moment pour enregistrer l'état final de la vue
propriétés.
![Image montrant la coordonnée inférieure de l'état final de la vue](https://developer.android.google.cn/static/images/guide/navigation/software-keyboard-4.png?authuser=9&hl=fr)
onStart()
pour enregistrer
l'état final.
L'extrait de code suivant présente un exemple d'appel à 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
est appelé lorsque les encarts changent dans le cadre de l'exécution d'une animation.
Vous pouvez donc l'ignorer et recevoir une notification à chaque image pendant le clavier
de l'animation. Mettez à jour les propriétés de la vue pour que celle-ci s'anime
synchronisation avec le clavier.
Toutes les modifications de mise en page sont terminées à ce stade. Par exemple, si vous utilisez
View.translationY
pour décaler la vue, la valeur diminue progressivement à chaque
de cette méthode et atteint finalement 0
à la position d'origine de la mise en page.
onProgress()
pour
synchroniser les animations.
L'extrait de code suivant présente un exemple d'appel à 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; }
Vous pouvez éventuellement ignorer onEnd
. Cette méthode est appelée après l'animation
est terminée. C'est le moment idéal pour éliminer toute modification temporaire.
Ressources supplémentaires
- WindowInsetsAnimation sur GitHub.