Görünümlerde tahmin edilen geri gitme animasyonları için destek ekleyin

Görünümler veya Compose'u kullanarak özel uygulama içi mülk animasyonları ve geçişleri, özel etkinlikler arası animasyonlar ve özel parça arası animasyonlar oluşturabilirsiniz. Compose yöntemini denemek için Tahmin edilen geri gitme animasyonları için destek ekleme başlıklı makaleyi inceleyin.

Progress API'yi kullanarak özel geçişler ekleme

AndroidX Activity 1.8.0-alpha01 veya sonraki sürümlerde, uygulamanızda tahmin edilen geri gitme hareketi için özel animasyonlar geliştirmek üzere Predictive Back Progress API'lerini kullanabilirsiniz. Progress API'leri görünümleri animasyonla hareketlendirmede faydalıdır ancak parçalar arasındaki geçişleri animasyonla hareketlendirirken sınırlamaları vardır. OnBackPressedCallback içinde, kullanıcı geri kaydırırken nesneleri canlandırmak için handleOnBackProgressed, handleOnBackCancelled ve handleOnBackStarted yöntemlerini kullanıma sunduk. Sistem tarafından sağlanan varsayılan animasyonlardan veya Material Component animasyonlarından daha fazlasını özelleştirmeniz gerekiyorsa bu yöntemleri kullanın.

Çoğu uygulamanın geriye dönük uyumlu AndroidX API'lerini kullanmasını bekliyoruz. Ancak OnBackAnimationCallback arayüzünde Android 14 ve sonraki sürümlerde test edilebilecek benzer platform API'leri de mevcuttur.

AndroidX Transitions ile Progress API'lerini kullanma

İlerleme Durumu API'leri, Android 14 ve sonraki sürümlerde AndroidX Transitions 1.5.0-alpha01 veya sonraki sürümleriyle birlikte kullanılarak Tahmini Geri Geçişleri oluşturulabilir.

  1. Kullanıcı geri kaydırdığında geçişleri oynatmak için beginDelayedTransition yerine TransitionManager#controlDelayedTransition kullanın.
  2. Geçişi handleOnBackStarted içinde oluşturun.
  3. Kullanıcının ne kadar geri kaydırdığını gösteren BackEvent.progress ile currentFraction arasında ilişki kurarak handleOnBackProgressed içinde geri etkinliğiyle geçişi oynatın.
  4. Kullanıcı handleOnBackPressed uygulamasında geri hareketini yaptıktan sonra geçişi tamamlayın.
  5. Son olarak, geçişin durumunu handleOnBackCancelled içinde sıfırlayın.

Aşağıdaki video, Kotlin kodu ve XML, OnBackPressedCallback ile uygulanan iki kutu arasındaki özel geçişi gösterir:

    class MyFragment : Fragment() {

    val transitionSet = TransitionSet().apply {
        addTransition(Fade(Fade.MODE_OUT))
        addTransition(ChangeBounds())
        addTransition(Fade(Fade.MODE_IN))
    }
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val callback = object : OnBackPressedCallback(enabled = false) {

            var controller: TransitionSeekController? = null

            @RequiresApi(34)
            override fun handleOnBackStarted(backEvent: BackEvent) {
                // Create the transition
                controller = TransitionManager.controlDelayedTransition(
                    binding.card,
                    transitionSet
                )
                changeTextVisibility(ShowText.SHORT)
            }

            @RequiresApi(34)
            override fun handleOnBackProgressed(backEvent: BackEvent) {
                // Play the transition as the user swipes back
                if (controller?.isReady == true) {
                    controller?.currentFraction = backEvent.progress
                }
            }

            override fun handleOnBackPressed() {
                // Finish playing the transition when the user commits back
                controller?.animateToEnd()
                this.isEnabled = false
            }

            @RequiresApi(34)
            override fun handleOnBackCancelled() {
                // If the user cancels the back gesture, reset the state
                transition(ShowText.LONG)
            }
        }

        binding.shortText.setOnClickListener {
            transition(ShowText.LONG)
            callback.isEnabled = true
        }

        this.requireActivity().onBackPressedDispatcher.addCallback(callback)
    }

    private fun transition(showText: ShowText) {
        TransitionManager.beginDelayedTransition(
            binding.card,
            transitionSet
        )
        changeTextVisibility(showText)
    }

    enum class ShowText { SHORT, LONG }
    private fun changeTextVisibility(showText: ShowText) {
        when (showText) {
            ShowText.SHORT -> {
                binding.shortText.isVisible = true
                binding.longText.isVisible = false
            }
            ShowText.LONG -> {
                binding.shortText.isVisible = false
                binding.longText.isVisible = true
            }
        }
    }
}
  
<?xml version="1.0" encoding="utf-8"?>
...
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/card"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        ...>

        <TextView
            android:id="@+id/short_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            ... />

        <TextView
            android:id="@+id/long_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone"
            .../>

    </androidx.constraintlayout.widget.ConstraintLayout>

Tahmini geri gitme geçişleriyle çalışırken aşağıdakileri göz önünde bulundurun:

  • Geçişin Tahmini Geri'yi destekleyip desteklemediğini kontrol etmek için isSeekingSupported simgesini kullanın.
  • Özel geçişleriniz için doğru değerini döndürmek üzere isSeekingSupported değerini geçersiz kılın.
  • Her animasyon için bir denetleyici oluşturun.
  • Tahmini Geri geçişleri, AndroidX geçişleriyle desteklenir ancak çerçeve geçişleriyle desteklenmez. Framework geçişlerini kullanmayı bırakıp bunun yerine Animator ve AndroidX geçişlerini kullanın.
  • Tahmini geri geçişleri, Android 14 ve sonraki sürümlerin yüklü olduğu cihazlarda desteklenir ve geriye dönük olarak uyumlu değildir.
  • XML sahneleriyle oluşturulan geçişler de desteklenir. handleOnBackStarted içinde TransitionSeekController değerini controlDelayedTransition sonucu yerine TransitionManager.createSeekController sonucuna ayarlayın.

Ek Kaynaklar