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

Görünümler veya Compose'u kullanarak tahmin edilen geri gitme hareketleriyle özel uygulama içi özellik animasyonları ve geçişleri, özel etkinlikler arası animasyonlar ve özel parçalar 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 Tahmin Edilen Geri Gitme İlerleme Durumu API'lerini kullanabilirsiniz. İlerleme Durumu API'leri, görünümleri canlandırmak için kullanışlıdır ancak parçalar arasındaki geçişleri canlandırırken sınırlamaları vardır. OnBackPressedCallback içinde, kullanıcı geri kaydırma hareketi yaparken nesnelere animasyon eklemek 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 Android 14 ve sonraki sürümlerde test edilebilecek OnBackAnimationCallback arayüzünde benzer platform API'leri de vardır.

AndroidX geçişleriyle Progress API'leri kullanma

Progress API'leri, Android 14 ve sonraki sürümlerde AndroidX Transitions 1.5.0-alpha01 veya sonraki sürümlerle birlikte kullanılarak tahmin edilen geri gitme 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. handleOnBackStarted içinde geçiş oluşturun.
  3. currentFraction ile BackEvent.progress arasında ilişki kurarak kullanıcının ne kadar geri kaydırdığını gösteren handleOnBackProgressed içindeki geri etkinliğiyle geçişi oynatın.
  4. Kullanıcı, handleOnBackPressed içinde geri hareketini yaptıktan sonra geçişi tamamlayın.
  5. Son olarak, handleOnBackCancelled içindeki geçişin durumunu sıfırlayın.

Aşağıdaki videoda, Kotlin kodunda ve XML'de, OnBackPressedCallback ile uygulanan iki kutu arasındaki özel geçiş gösterilmektedir:

    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>

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

  • Geçişin, tahmin edilen geri gitme özelliğini destekleyip desteklemediğini kontrol etmek için isSeekingSupported kullanın.
  • Özel geçişleriniz için true değerini döndürmek üzere isSeekingSupported yöntemini geçersiz kılın.
  • Her animasyon için bir denetleyici oluşturun.
  • Tahmin edilen geri gitme geçişleri, AndroidX geçişleriyle desteklenir ancak çerçeve geçişleriyle desteklenmez. Framework geçişlerinden uzaklaşın ve bunun yerine Animator ile AndroidX geçişlerini kullanın.
  • Tahmin edilen geri gitme geçişleri, Android 14 ve sonraki sürümleri çalıştıran cihazlarda desteklenir ve geriye dönük uyumlu değildir.
  • XML sahneleriyle oluşturulan geçişler de desteklenir. handleOnBackStarted içinde TransitionSeekController değerinizi controlDelayedTransition sonucuna değil, TransitionManager.createSeekController sonucuna ayarlayın.

Ek Kaynaklar