Uygulamanız, WindowInsetsCompat
sayesinde sistem çubuklarıyla etkileşimine 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
aracını da kullanabilir.
Ön koşullar
Yazılım klavyesi için kontrol ve animasyon ayarlamadan önce uygulamanızı uçtan uca görüntüleyecek şekilde yapılandırın. Bu, sistem çubukları ve dokunmatik klavye gibi sistem penceresi alt öğelerini işleyebilmesini sağlar.
Klavye yazılımının görünürlüğünü kontrol etme
Yazılım klavye görünürlüğünü kontrol etmek için WindowInsets
öğesini 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 klavyesinin görünürlüğündeki değişiklikleri gözlemlemek için ViewCompat.setOnApplyWindowInsetsListener
aracını da 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 dokunulduğunda, aşağıdaki örnekte gösterildiği gibi klavye, ekranın alt kısmından yerine kayarak yerine oturur:
Şekil 2'deki "Senkronize edilmemiş" etiketli örnek, Android 10'daki (API düzeyi 29) varsayılan davranışı göstermektedir. Burada metin alanı ve uygulamanın içeriği, klavyenin animasyoniyle senkronize etmek yerine yerine yerleşir. Bu davranış, görsel olarak rahatsız edici olabilir.
Android 11 (API düzeyi 30) ve sonraki sürümlerde uygulama geçişini, ekranın altından yukarı ve aşağı kayan klavyeyle senkronize etmek için
WindowInsetsAnimationCompat
kullanabilirsiniz. Şekil 2'deki "Senkronize edilmiş" etiketli örnekte gösterildiği gibi bu daha yumuşak görünür.
WindowInsetsAnimationCompat.Callback
simgesini, 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()
.
Düzen herhangi bir değişiklik yapmadan önce onPrepare()
komutunu çağırarak başlayın.
onPrepare
, bir insets animasyonu başladığında ve görünümler animasyon nedeniyle yeniden yerleştirilmeden önce çağrılır. Başlangıç durumunu (bu örnekte, görünümün alt koordinatı) kaydetmek için bunu 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=7&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 iç içe ekleme 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 bunu kullanabilirsiniz. Görünümlerden herhangi birine ayarlanmış bir OnApplyWindowInsetsListener
geri çağırmanız varsa zaten bu noktada çağrılır. Bu, görünüm özelliklerinin bitiş durumunu kaydetmek için iyi bir zamandır.
![Görünümün bitiş durumu alt koordinatını gösteren resim](https://developer.android.com/static/images/guide/navigation/software-keyboard-4.png?authuser=7&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; }
onProgress
, animasyonun çalıştırılması kapsamında ayarlar değiştiğinde çağrılır. Böylece, klavye animasyonu sırasında bunu geçersiz kılabilir ve her karede bildirim alabilirsiniz. Görünüm özelliklerini, görünümün klavyeyle senkronize olarak canlandırılacağı şekilde güncelleyin.
Bu noktada tüm düzen değişiklikleri tamamlanmıştır. Örneğin, görünümü değiştirmek için View.translationY
kullanırsanız değer, bu yöntemin her çağrısında kademeli olarak azalır ve sonunda orijinal düzen konumuna 0
ulaşır.
onProgress()
kullanılıyor.
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 bittikten
sonra çağrılır. Bu, geçici tüm değişiklikleri temizlemek için iyi bir zamandır.
Ek kaynaklar
- WindowInsetsAnimation ve GitHub'da çalışıyor.