Aggiungi il supporto per le animazioni predittive per Indietro in Views

Puoi creare animazioni e transizioni di proprietà in-app personalizzate, animazioni tra attività personalizzate e animazioni tra fragment personalizzate con i gesti di Indietro predittivo utilizzando Views o Compose. Per provare il metodo Compose, consulta Aggiungere il supporto per le animazioni di Indietro predittivo.

Aggiungere transizioni personalizzate utilizzando l'API Progress

Con AndroidX Activity 1.8.0-alpha01 o versioni successive, puoi utilizzare le API Predictive Back Progress per sviluppare animazioni personalizzate per il gesto di Indietro predittivo nella tua app. Le API Progress sono utili per animare le visualizzazioni, ma presentano limitazioni quando si animano le transizioni tra i fragment. In OnBackPressedCallback abbiamo introdotto i metodi handleOnBackProgressed, handleOnBackCancelled e handleOnBackStarted per animare gli oggetti mentre l'utente scorre indietro. Utilizza questi metodi se devi personalizzare più delle animazioni predefinite fornite dal sistema o le animazioni dei componenti Material.

Prevediamo che la maggior parte delle app utilizzi le API AndroidX compatibili con le versioni precedenti, ma sono disponibili anche API della piattaforma simili all'interno dell'OnBackAnimationCallbackinterfaccia da testare su Android 14 e versioni successive.

Utilizzare le API Progress con le transizioni AndroidX

Le API Progress possono essere utilizzate con le transizioni AndroidX 1.5.0-alpha01 o versioni successive su Android 14 e versioni successive per creare transizioni di Indietro predittivo.

  1. Utilizza TransitionManager#controlDelayedTransition anziché beginDelayedTransition per riprodurre le transizioni mentre l'utente scorre indietro.
  2. Crea la transizione all'interno di handleOnBackStarted.
  3. Riproduci la transizione con l'evento Indietro all'interno di handleOnBackProgressed mettendo in relazione currentFraction con BackEvent.progress, che mostra la distanza percorsa dall'utente con lo scorrimento indietro.
  4. Completa la transizione dopo che l'utente ha eseguito il gesto di Indietro in handleOnBackPressed.
  5. Infine, reimposta lo stato della transizione all'interno di handleOnBackCancelled.

Il seguente video, il codice Kotlin e il codice XML mostrano una transizione personalizzata tra due riquadri implementata 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>

Quando lavori con le transizioni di Indietro predittivo, tieni presente quanto segue:

  • Utilizza isSeekingSupported per verificare se la transizione supporta Indietro predittivo.
  • Esegui l'override di isSeekingSupported per restituire true per le transizioni personalizzate.
  • Crea un controller per animazione.
  • Le transizioni di Indietro predittivo sono supportate con le transizioni AndroidX, ma non con le transizioni del framework. Esegui la migrazione dalle transizioni del framework e utilizza invece Animator e le transizioni AndroidX.
  • Le transizioni di Indietro predittivo sono supportate sui dispositivi con Android 14 e versioni successive e non sono compatibili con le versioni precedenti.
  • Sono supportate anche le transizioni create con scene XML. In handleOnBackStarted, imposta TransitionSeekController sul risultato di TransitionManager.createSeekController anziché sul risultato di controlDelayedTransition.

Risorse aggiuntive