Uygulamanız, WindowInsetsCompat
kullanarak dokunmatik klavyeyi (IME olarak da adlandırılır) sistem çubuklarıyla etkileşim şekline benzer şekilde sorgulayıp kontrol edebilir. Uygulamanız, yazılım klavyesi açıldığında veya kapatıldığında sorunsuz geçişler oluşturmak için WindowInsetsAnimationCompat
aracını da kullanabilir.
Ön koşullar
Yazılım klavyesi için kontrolü ve animasyonu ayarlamadan önce, uygulamanızı uçtan uca görüntüleyecek şekilde yapılandırın. Bu işlem, sistem çubukları ve dokunmatik klavye gibi sistem penceresi eklerini işlemesine olanak tanır.
Klavye yazılımı görünürlüğünü kontrol etme
Yazılım klavyesinin görünürlüğünü kontrol etmek için WindowInsets
düğmesini 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 eder
Aşağıdaki örnekte gösterildiği gibi, metin giriş alanına dokunan bir kullanıcı, klavyenin ekranın alt kısmından yerine kaymasına neden olur:
Şekil 2'deki "Senkronize edilmemiş" etiketli örnekte, Android 10'daki (API düzeyi 29) varsayılan davranış gösterilmiştir. Bu davranışta, uygulama metin alanı ve içeriği klavyenin animasyonuyla senkronize edilmeden yerine tutturulur. Bu davranış görsel olarak sarsıcı olabilir.
Android 11 (API düzeyi 30) ve sonraki sürümlerde, uygulamanın geçişini klavyenin ekranın altından yukarı ve aşağı kaydırmasıyla senkronize etmek için
WindowInsetsAnimationCompat
uygulamasını kullanabilirsiniz. Bu işlem daha düzgün görünür. Şekil 2'deki "Senkronize edilmiş" etiketli örnekte gösterildiği gibi.
WindowInsetsAnimationCompat.Callback
'i, klavye animasyonuyla senkronize edilecek görünümle 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
ürününde geçersiz kılmanın birkaç yöntemi vardır: onPrepare()
, onStart()
, onProgress()
ve onEnd()
.
Herhangi bir düzen değişikliğinden önce onPrepare()
çağrısıyla başlayın.
onPrepare
, bir inset animasyonu başladığında ve görünümler animasyon nedeniyle yeniden düzenlenmeden önce çağrılır. Bunu, görünümün alt koordinatı olan
başlangıç durumunu kaydetmek için kullanabilirsiniz.
![Kök görünümünün başlangıç durumu alt koordinatını gösteren resim.](https://developer.android.com/static/images/guide/navigation/software-keyboard-3.png?authuser=5&hl=tr)
onPrepare()
kullanılıyor.
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 insets animasyonu başladığında onStart
çağrılır. Bunu, tüm görünüm özelliklerini düzen değişikliklerinin son durumuna ayarlamak için kullanabilirsiniz. Görüntülemelerden herhangi birine ayarlanmış bir OnApplyWindowInsetsListener
geri çağırmanız varsa zaten bu noktada çağrılır. Bu, görünüm özelliklerinin son durumunu kaydetmek için iyi bir zamandır.
![Görünümün bitiş durumunun alt koordinatını gösteren resim](https://developer.android.com/static/images/guide/navigation/software-keyboard-4.png?authuser=5&hl=tr)
onStart()
kullanılıyor.
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; }
Bir animasyonun çalıştırılması sırasında ekler değiştiğinde onProgress
çağrılır. Böylece bunu geçersiz kılabilir ve klavye animasyonu sırasında her karede bilgilendirilebilirsiniz. Görünüm özelliklerini, görünümün klavyeyle senkronizasyon sırasında canlandırılacağı ş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 değer bu yöntemin her çağrısı için kademeli olarak azalır ve sonunda 0
değerine ulaşarak orijinal düzen konumuna ulaşır.
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
politikasını 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 türünde.