Korzystając z WindowInsetsCompat
,
aplikacja może używać klawiatury ekranowej (zwanej też
IME) podobny do
sposób jego interakcji z paskami systemowymi. Aplikacja może też używać tych funkcji:
WindowInsetsAnimationCompat
w celu utworzenia płynnych przejść po otwarciu lub zamknięciu klawiatury programowej.
Wymagania wstępne
Przed skonfigurowaniem elementów sterujących i animacji dla klawiatury programowej skonfiguruj wyświetlanie w całości od krawędzi do krawędzi. Dzięki temu obsługuje wstawki okien systemowych, takie jak paski systemowe i klawiaturę ekranową.
Sprawdź widoczność oprogramowania klawiatury
Użyj WindowInsets
, aby sprawdzić oprogramowanie
widoczność klawiatury.
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;
Możesz też użyć
ViewCompat.setOnApplyWindowInsetsListener
by obserwować zmiany w widoczności klawiatury programowej.
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; });
Synchronizuj animację z klawiaturą programową
Gdy użytkownik klika pole do wprowadzania tekstu, klawiatura przesuwa się z jak widać w tym przykładzie:
Przykład oznaczony jako „Niezsynchronizowana” na ilustracji 2 pokazuje domyślne zachowanie w Androidzie 10 (poziom interfejsu API 29), w którym pole tekstowe i zawartość aplikacji wskoczy na miejsce, zamiast synchronizować się z klawiaturą animacja – zachowanie, które może być atrakcyjne wizualnie.
W Androidzie 11 (poziom API 30) i nowszym możesz używać
WindowInsetsAnimationCompat
, aby zsynchronizować przenoszenie aplikacji z: klawiaturę przesuwa się w górę i w dół ekranu. Wygląda tak jak w przykładzie z etykietą „Zsynchronizowane”. na ilustracji 2.
Skonfiguruj
WindowInsetsAnimationCompat.Callback
w widoku, który ma być zsynchronizowany z animacją klawiatury.
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. });
Istnieje kilka metod zastępowania ustawień w WindowInsetsAnimationCompat.Callback
,
mianowicie
onPrepare()
,
onStart()
,
onProgress()
oraz
onEnd()
.
Zacznij od wywołania onPrepare()
przed zmianą układu.
Funkcja onPrepare
jest wywoływana, gdy rozpoczyna się animacja wcięcia i przed wyświetleniami.
są rozłożone z powodu animacji. Można w nim zapisać stan początkowy,
czyli w tym przypadku dolna współrzędna widoku.
![Obraz przedstawiający dolną współrzędną stanu początkowego widoku głównego.](https://developer.android.com/static/images/guide/navigation/software-keyboard-3.png?authuser=9&hl=pl)
onPrepare()
do:
rejestrować stan początkowy.
Ten fragment kodu zawiera przykładowe wywołanie funkcji 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(); }
Funkcja onStart
jest wywoływana, gdy rozpoczyna się animacja wcięcia. Możesz użyć tej opcji, aby ustawić wszystkie
właściwości widoku, aby zmienić stan końcowy. Jeśli posiadasz
Wywołanie zwrotne OnApplyWindowInsetsListener
zostało ustawione na dowolny z widoków, jest już
w tym miejscu. To dobry moment na zapisanie stanu końcowego widoku
usług.
![Obraz przedstawiający dolną współrzędną stanu końcowego widoku](https://developer.android.com/static/images/guide/navigation/software-keyboard-4.png?authuser=9&hl=pl)
onStart()
o stanie końcowym.
Ten fragment kodu zawiera przykładowe wywołanie funkcji 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; }
Funkcja onProgress
jest wywoływana, gdy wstawki zmieniają się w trakcie animacji.
Można je więc zastąpić i otrzymywać powiadomienia przy każdej ramce podczas korzystania z klawiatury.
animację. Zaktualizuj właściwości widoku, tak aby był animowany
synchronizację z klawiaturą.
Na tym etapie wszystkie zmiany układu są zakończone. Na przykład, jeśli używasz
View.translationY
, aby przesunąć widok; wartość stopniowo się zmniejsza przy każdym
i ostatecznie dochodzi do 0
do pierwotnej pozycji układu.
onProgress()
do:
synchronizują animacje.
Ten fragment kodu zawiera przykładowe wywołanie funkcji 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; }
Możesz też zastąpić zasadę onEnd
. Ta metoda jest wywoływana po animacji
koniec. To dobry moment na usunięcie wszelkich tymczasowych zmian.
Dodatkowe materiały
- Animacja WindowInsetsAnimation w GitHubie.