Se agregó compatibilidad con animaciones de atrás predictivo en Views

Puedes crear animaciones y transiciones personalizadas de propiedades integradas en la app, animaciones personalizadas con varias actividades y animaciones personalizadas con varios fragmentos con gestos de atrás predictivo usando Views o Compose. Para probar la forma de Compose, consulta Cómo agregar compatibilidad con animaciones de atrás predictivo.

Cómo agregar transiciones personalizadas con la API de Progress

Con AndroidX Activity 1.8.0-alpha01 o versiones posteriores, puedes usar las APIs de Predictive Back Progress para desarrollar animaciones personalizadas para el gesto atrás predictivo en tu app. Las APIs de Progress son útiles para animar vistas, pero tienen limitaciones cuando se animan transiciones entre fragmentos. En OnBackPressedCallback, presentamos los métodos handleOnBackProgressed, handleOnBackCancelled y handleOnBackStarted para animar objetos mientras el usuario desliza hacia atrás. Usa estos métodos si necesitas personalizar más que las animaciones predeterminadas que proporciona el sistema o las animaciones de los componentes de Material.

Se espera que la mayoría de las apps usen las APIs de AndroidX retrocompatibles, pero también hay APIs de plataforma similares dentro de la interfaz de OnBackAnimationCallback disponibles para probar en Android 14 y versiones posteriores.

Cómo usar las APIs de Progress con transiciones de AndroidX

Las APIs de Progress se pueden usar con las transiciones de AndroidX 1.5.0-alpha01 o versiones posteriores en Android 14 y versiones posteriores para crear transiciones de atrás predictivo.

  1. Usa TransitionManager#controlDelayedTransition en lugar de beginDelayedTransition para reproducir transiciones mientras el usuario desliza el dedo hacia atrás.
  2. Crea la transición dentro de handleOnBackStarted.
  3. Para reproducir la transición con el evento de atrás dentro de handleOnBackProgressed, vincula currentFraction con BackEvent.progress, lo que expone cuán lejos el usuario deslizó hacia atrás.
  4. Finaliza la transición después de que el usuario confirme el gesto atrás en handleOnBackPressed.
  5. Por último, restablece el estado de la transición en handleOnBackCancelled.

En el siguiente video, se muestra una transición personalizada con código Kotlin y XML entre dos cuadros implementada con OnBackPressedCallback:

    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>

Cuando trabajes con transiciones de atrás predictivo, ten en cuenta lo siguiente:

  • Usa isSeekingSupported para verificar si la transición admite el gesto atrás predictivo.
  • Anula isSeekingSupported para que se muestre verdadero en tus transiciones personalizadas.
  • Crea un controlador por animación.
  • Las transiciones de atrás predictivo son compatibles con las transiciones de AndroidX, pero no con las transiciones del framework. Migra de las transiciones del framework y usa Animator y las transiciones de AndroidX en su lugar.
  • Las transiciones del gesto atrás predictivo se admiten en dispositivos que ejecutan Android 14 y versiones posteriores, y no ofrecen retrocompatibilidad.
  • También se admiten las transiciones creadas con escenas XML. En handleOnBackStarted, establece tu TransitionSeekController como el resultado de TransitionManager.createSeekController en lugar del resultado de controlDelayedTransition.

Recursos adicionales