WindowInsetsCompat
'yi kullanarak uygulamanız, sistem çubuklarıyla etkileşim kurma şekline benzer şekilde, dokunmatik klavyeyi (IME olarak da bilinir) sorgulayabilir ve kontrol edebilir. Uygulamanız, yazılım klavyesi açıldığında veya kapatıldığında sorunsuz geçişler oluşturmak için
WindowInsetsAnimationCompat
de kullanabilir.
Ön koşullar
Yazılım klavyesi için kontrol ve animasyon ayarlamadan önce uygulamanızı uçtan uca gösterecek şekilde yapılandırın. Bu, sistem çubukları ve dokunmatik klavye gibi sistem penceresi yerleşimlerinin işlenmesini sağlar.
Klavye yazılımının görünürlüğünü kontrol etme
Yazılım klavyesinin görünürlüğünü kontrol etmek için WindowInsets
simgesini kullanın.
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;
Alternatif olarak, yazılım klavyesi görünürlüğündeki değişiklikleri gözlemlemek için
ViewCompat.setOnApplyWindowInsetsListener
kullanabilirsiniz.
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; });
Animasyonu yazılım klavyesiyle senkronize etme
Bir kullanıcının metin giriş alanına dokunması, klavyenin ekranın alt kısmından kayarak yerine oturmasına neden olur. Bu durum aşağıdaki örnekte gösterilmiştir:
Şekil 2'deki "Senkronize edilmemiş" etiketli örnekte, Android 10'daki (API düzeyi 29) varsayılan davranış gösterilmektedir. Bu davranışta, metin alanı ve uygulamanın içeriği, klavyenin animasyonuyla senkronize olmak yerine yerine oturur. Bu davranış görsel olarak rahatsız edici olabilir.
Android 11 (API düzeyi 30) ve sonraki sürümlerde, uygulamanın geçişini klavyenin ekranın alt kısmından yukarı ve aşağı kaymasıyla senkronize etmek için
WindowInsetsAnimationCompat
kullanabilirsiniz. Bu, Şekil 2'deki "Senkronize" etiketli örnekte gösterildiği gibi daha sorunsuz görünür.
Klavye animasyonuyla senkronize edilecek görünümü kullanarak
WindowInsetsAnimationCompat.Callback
yapılandırın.
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. });
WindowInsetsAnimationCompat.Callback
içinde geçersiz kılmak için çeşitli yöntemler vardır.
Örneğin
onPrepare()
,
onStart()
,
onProgress()
,
ve
onEnd()
.
Düzen değişikliklerinden önce onPrepare()
ile aramaya başlayın.
onPrepare
, bir iç kenar animasyonu başlatıldığında ve görünümler animasyon nedeniyle yeniden düzenlenmeden önce çağrılır. Bu işlevi, başlangıç durumunu (bu örnekte görünümün alt koordinatı) kaydetmek için kullanabilirsiniz.

onPrepare()
kullanılır.
Aşağıdaki snippet'te onPrepare
için örnek bir çağrı gösterilmektedir:
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(); }
Bir içe yerleştirme animasyonu başladığında onStart
çağrılır. Tüm görünüm özelliklerini düzen değişikliklerinin son durumuna ayarlamak için bu özelliği kullanabilirsiniz. Görünümlerden herhangi birine ayarlanmış bir OnApplyWindowInsetsListener
geri arama varsa bu noktada zaten çağrılmıştır. Bu, görünüm özelliklerinin son durumunu kaydetmek için iyi bir zamandır.

onStart()
kullanma.
Aşağıdaki snippet'te onStart
için örnek bir çağrı gösterilmektedir:
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
, animasyon çalıştırılırken yerleşimler değiştiğinde çağrılır. Bu nedenle, klavye animasyonu sırasında her karede geçersiz kılabilir ve bildirim alabilirsiniz. Görünüm özelliklerini, görünümün klavye ile senkronize olacak şekilde animasyon oluşturacak şekilde güncelleyin.
Bu noktada tüm düzen değişiklikleri tamamlanmıştır. Örneğin, görünümü kaydırmak için View.translationY
kullanırsanız bu yöntemin her çağrısında değer kademeli olarak azalır ve sonunda orijinal düzen konumuna ulaşmak için 0
olur.
onProgress()
kullanma.
Aşağıdaki snippet'te onProgress
için örnek bir çağrı gösterilmektedir:
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; }
İsteğe bağlı olarak onEnd
geçersiz kılabilirsiniz. Bu yöntem, animasyon sona erdikten sonra çağrılır. Bu, geçici değişiklikleri temizlemek için iyi bir zamandır.
Ek kaynaklar
- GitHub'da WindowInsetsAnimation.