Dengan menggunakan WindowInsetsCompat
,
aplikasi Anda dapat mengkueri dan mengontrol keyboard di layar (juga disebut
IME) yang mirip dengan
berinteraksi dengan bilah sistem. Aplikasi Anda juga
dapat menggunakan
WindowInsetsAnimationCompat
untuk membuat transisi yang mulus saat {i>keyboard<i} virtual dibuka atau ditutup.
Prasyarat
Sebelum menyiapkan kontrol dan animasi untuk keyboard virtual, konfigurasikan aplikasi Anda untuk menampilkan layar penuh. Hal ini memungkinkan sistem ini menangani inset jendela sistem seperti kolom sistem dan keyboard virtual.
Periksa visibilitas software keyboard
Gunakan WindowInsets
untuk memeriksa software
visibilitas keyboard.
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;
Atau, Anda bisa menggunakan
ViewCompat.setOnApplyWindowInsetsListener
untuk mengamati perubahan pada visibilitas {i>keyboard<i}
perangkat lunak.
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; });
Menyinkronkan animasi dengan keyboard software
Pengguna mengetuk bidang {i>input <i}teks menyebabkan keyboard bergeser ke tempatnya dari bagian bawah layar, seperti yang ditunjukkan dalam contoh berikut:
Contoh berlabel "Unsynchronized" pada gambar 2 menunjukkan perilaku default di Android 10 (API level 29), dengan kolom teks dan konten aplikasi terpasang dengan benar alih-alih menyinkronkannya dengan animasi—perilaku yang secara visual tampak mengagetkan.
Di Android 11 (level API 30) dan yang lebih tinggi, Anda dapat menggunakan
WindowInsetsAnimationCompat
untuk menyinkronkan transisi aplikasi dengan {i>keyboard<i} yang bergeser ke atas dan ke bawah dari bagian bawah layar. Ini terlihat lebih halus, seperti ditunjukkan dalam contoh berlabel "Disinkronkan" pada gambar 2.
Konfigurasi
WindowInsetsAnimationCompat.Callback
dengan tampilan yang disinkronkan dengan animasi keyboard.
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. });
Ada beberapa metode yang dapat diganti di WindowInsetsAnimationCompat.Callback
,
yaitu
onPrepare()
,
onStart()
,
onProgress()
,
dan
onEnd()
.
Mulai dengan memanggil onPrepare()
sebelum tata letak apa pun berubah.
onPrepare
dipanggil saat animasi inset dimulai dan sebelum tampilan
disusun ulang karena adanya animasi. Anda dapat menggunakannya
untuk menyimpan status awal,
yang dalam hal ini adalah
koordinat bawah tampilan.
Cuplikan berikut menunjukkan contoh panggilan ke 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
dipanggil saat animasi inset dimulai. Anda dapat menggunakannya
untuk mengatur
properti tampilan ke keadaan akhir
dari perubahan tata letak. Anda memiliki
Callback OnApplyWindowInsetsListener
yang disetel ke tampilan mana pun, sudah
dipanggil pada tahap ini. Inilah saat yang tepat untuk menyimpan status akhir tampilan
properti baru.
Cuplikan berikut menunjukkan contoh panggilan ke 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
dipanggil saat inset berubah sebagai bagian dari menjalankan animasi,
sehingga Anda dapat menggantinya dan diberi tahu pada setiap frame selama keyboard
animasi. Perbarui properti tampilan agar tampilan dianimasikan dalam
sinkronisasi dengan keyboard.
Semua perubahan tata letak sudah selesai pada tahap ini. Misalnya, jika Anda menggunakan
View.translationY
untuk menggeser tampilan, nilai akan menurun secara bertahap untuk setiap
pemanggilan metode ini dan akhirnya mencapai 0
ke posisi tata letak asal.
Cuplikan berikut menunjukkan contoh panggilan ke 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; }
Jika ingin, Anda dapat mengganti onEnd
. Metode ini dipanggil setelah animasi
sudah berakhir. Ini adalah saat yang tepat untuk menghapus semua perubahan sementara.
Referensi lainnya
- WindowInsetsAnimation di GitHub.