Aggiunta del supporto per il gesto Indietro predittivo

Figura 1. Mockup dell'aspetto e del funzionamento del gesto di ritorno predittivo su uno smartphone

Indietro predittivo, una funzionalità di navigazione con gesti, consente agli utenti di visualizzare l'anteprima della destinazione del gesto di scorrimento verso il retro.

Ad esempio, l'utilizzo di un gesto Indietro può mostrare un'anteprima animata della schermata Home dietro l'app, come mostrato nel mockup in Figura 1.

A partire da Android 15, l'opzione per gli sviluppatori per le animazioni di ritorno predittive non è più disponibile. Le animazioni di sistema, come il ritorno alla schermata Home, il passaggio da un'attività all'altra e il passaggio da un'attività all'altra, ora vengono visualizzate per le app che hanno attivato il gesto Indietro predittivo, in toto o a livello di attività.

Puoi testare questa animazione di ritorno alla home page (come descritto nella sezione successiva di questa pagina).

Per supportare il gesto di ritorno predittivo è necessario aggiornare l'app utilizzando l'API OnBackPressedCallback AppCompat 1.6.0-alpha05 (AndroidX) o versioni successive compatibili con le versioni precedenti o la nuova API di piattaforma OnBackInvokedCallback. La maggior parte delle app utilizza l'API AndroidX compatibile con le versioni precedenti.

Questo aggiornamento fornisce un percorso di migrazione per intercettare correttamente la navigazione a ritroso, che prevede la sostituzione delle intercettazioni a ritroso di KeyEvent.KEYCODE_BACK e di qualsiasi classe con metodi onBackPressed come Activity e Dialog con le nuove API di sistema Back.

Codelab e video su Google I/O

Oltre a utilizzare questa documentazione in questa pagina, prova il nostro codelab. Fornisce un'implementazione di casi d'uso comuni di un WebView che gestisce il gesto di ritorno predittivo utilizzando le API AndroidX Activity.

Puoi anche guardare il nostro video della conferenza Google I/O, che illustra ulteriori esempi di implementazione delle API AndroidX e della piattaforma.

Aggiornare un'app che utilizza la navigazione a ritroso predefinita

Aggiornare l'app per supportare questa funzionalità è semplice se l'app non implementa alcun comportamento personalizzato per il pulsante Indietro (in altre parole, lascia la gestione del pulsante Indietro al sistema). Attiva questa funzionalità come descritto in questa guida.

Se la tua app utilizza i frammenti o il componente di navigazione, esegui anche l'upgrade a AndroidX Activity 1.6.0-alpha05 o versioni successive.

Aggiornare un'app che utilizza la navigazione a ritroso personalizzata

Se la tua app implementa un comportamento personalizzato per il pulsante Indietro, esistono diversi percorsi di migrazione, a seconda che utilizzi AndroidX e di come gestisce la navigazione a ritroso.

La tua app utilizza AndroidX In che modo la tua app gestisce la navigazione a ritroso Percorso di migrazione consigliato (link in questa pagina)
API AndroidX Eseguire la migrazione di un'implementazione AndroidX esistente
API di piattaforma non supportate Eseguire la migrazione di un'app AndroidX contenente API di navigazione a ritroso non supportate alle API AndroidX
No API di piattaforma non supportate, per le quali è possibile eseguire la migrazione Eseguire la migrazione di un'app che utilizza API di navigazione a ritroso non supportate alle API di piattaforma
API delle piattaforme non supportate, ma impossibile eseguire la migrazione Rimandare l'attivazione finché non diventa una funzionalità obbligatoria

Eseguire la migrazione di un'implementazione della navigazione a ritroso di AndroidX

Questo caso d'uso è il più comune (e il più consigliato). Si applica alle app nuove o esistenti che implementano la gestione della navigazione con gesti personalizzati con OnBackPressedDispatcher, come descritto in Fornire la navigazione a ritroso personalizzata.

Se la tua app rientra in questa categoria, svolgi i passaggi che seguono per supportare il gesto Indietro predittivo:

  1. Per assicurarti che le API che utilizzano già le API OnBackPressedDispatcher (come i frammenti e il componente di navigazione) funzionino perfettamente con il gesto di ritorno predittivo, esegui l'upgrade a AndroidX Activity 1.6.0-alpha05.

    // In your build.gradle file:
    dependencies {
    
    // Add this in addition to your other dependencies
    implementation "androidx.activity:activity:1.6.0-alpha05"
    
  2. Attiva il gesto Indietro predittivo, come descritto in questa pagina.

Eseguire la migrazione di un'app AndroidX contenente API di navigazione a ritroso non supportate alle API AndroidX

Se la tua app utilizza librerie AndroidX, ma implementa o fa riferimento ad API di navigazione a ritroso non supportate, dovrai eseguire la migrazione all'utilizzo delle API AndroidX per supportare il nuovo comportamento.

Per eseguire la migrazione delle API non supportate alle API AndroidX:

  1. Esegui la migrazione della logica di gestione del pulsante Indietro del sistema a OnBackPressedDispatcher di AndroidX con un'implementazione di OnBackPressedCallback. Per indicazioni dettagliate, consulta Fornire la navigazione a ritroso personalizzata.

  2. Disattiva OnBackPressedCallback quando vuoi interrompere l'intercettazione del gesto Indietro.

  3. Interrompi l'intercettazione degli eventi arretrati tramite OnBackPressed o KeyEvent.KEYCODE_BACK.

  4. Assicurati di eseguire l'upgrade a AndroidX Activity 1.6.0-alpha05.

    // In your build.gradle file:
    dependencies {
    
    // Add this in addition to your other dependencies
    implementation "androidx.activity:activity:1.6.0-alpha05"
    
  5. Dopo aver eseguito correttamente la migrazione dell'app, attiva il gesto di ritorno predittivo (come descritto su questa pagina) per vedere l'animazione di sistema di ritorno alla home page.

Esegui la migrazione di un'app che utilizza API di navigazione a ritroso non supportate alle API di piattaforma

Se la tua app non può utilizzare le librerie AndroidX e, al contrario, implementa o fa riferimento alla navigazione a ritroso personalizzata utilizzando le API non supportate, devi eseguire la migrazione all'API di piattaforma OnBackInvokedCallback.

Per eseguire la migrazione delle API non supportate all'API della piattaforma, completa i seguenti passaggi:

  1. Utilizza la nuova API OnBackInvokedCallback sui dispositivi con Android 13 o versioni superiori e le API non supportate sui dispositivi con Android 12 o versioni precedenti.

  2. Registra la logica di back-up personalizzata in OnBackInvokedCallback con onBackInvokedDispatcher. In questo modo, l'attività in corso non viene completata e il tuo callback ha la possibilità di reagire all'azione Indietro quando l'utente completa la navigazione a ritroso del sistema.

  3. Quando è tutto pronto, annulla la registrazione del OnBackInvokedCallback per interrompere l'intercettazione del gesto di ritorno. In caso contrario, gli utenti potrebbero notare comportamenti indesiderati quando utilizzano il pulsante Indietro del sistema, ad esempio "bloccarsi" tra le visualizzazioni e dover forzare l'uscita forzata dall'app.

    Ecco un esempio di come eseguire la migrazione della logica da onBackPressed:

    Kotlin

    @Override
    fun onCreate() {
        if (BuildCompat.isAtLeastT()) {
            onBackInvokedDispatcher.registerOnBackInvokedCallback(
                OnBackInvokedDispatcher.PRIORITY_DEFAULT
            ) {
                /**
                 * onBackPressed logic goes here. For instance:
                 * Prevents closing the app to go home screen when in the
                 * middle of entering data to a form
                 * or from accidentally leaving a fragment with a WebView in it
                 *
                 * Unregistering the callback to stop intercepting the back gesture:
                 * When the user transitions to the topmost screen (activity, fragment)
                 * in the BackStack, unregister the callback by using
                 * OnBackInvokeDispatcher.unregisterOnBackInvokedCallback
                 * (https://developer.android.com/reference/kotlin/android/window/OnBackInvokedDispatcher#unregisteronbackinvokedcallback)
                 */
            }
        }
    }

    Java

    @Override
    void onCreate() {
      if (BuildCompat.isAtLeastT()) {
        getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
            OnBackInvokedDispatcher.PRIORITY_DEFAULT,
            () -> {
              /**
               * onBackPressed logic goes here - For instance:
               * Prevents closing the app to go home screen when in the
               * middle of entering data to a form
               * or from accidentally leaving a fragment with a WebView in it
               *
               * Unregistering the callback to stop intercepting the back gesture:
               * When the user transitions to the topmost screen (activity, fragment)
               * in the BackStack, unregister the callback by using
               * OnBackInvokeDispatcher.unregisterOnBackInvokedCallback
               * (https://developer.android.com/reference/kotlin/android/view/OnBackInvokedDispatcher#unregisteronbackinvokedcallback)
               */
            }
        );
      }
    }
  4. Interrompi l'intercettazione degli eventi Indietro tramite OnBackPressed o KeyEvent.KEYCODE_BACK per Android 13 e versioni successive.

  5. Dopo aver eseguito la migrazione dell'app, attiva il gesto di ritorno predittivo (come descritto su questa pagina) in modo che OnBackInvokedCallback venga applicato.

Puoi registrare un OnBackInvokedCallback con PRIORITY_DEFAULT o PRIORITY_OVERLAY, che non è disponibile nell'analogo AndroidX OnBackPressedCallback. La registrazione di un callback con PRIORITY_OVERLAY è utile in alcuni casi.

Questo vale quando esegui la migrazione da onKeyPreIme() e il tuo callback deve ricevere il gesto Indietro anziché un IME aperto. Gli IME registrano i callback con PRIORITY_DEFAULT quando vengono aperti. Registra il callback con PRIORITY_OVERLAY per assicurarti che OnBackInvokedDispatcher invii il gesto Indietro al callback anziché l'IME aperto.

Attiva il gesto Indietro predittivo

Una volta stabilito come aggiornare l'app in base alla tua richiesta, attiva il supporto del gesto di ritorno predittivo.

Per attivare la funzionalità, in AndroidManifest.xml, nel tag <application>, imposta il android:enableOnBackInvokedCallback flag su true.

<application
    ...
    android:enableOnBackInvokedCallback="true"
    ... >
...
</application>

Se non specifichi un valore, il valore predefinito è false e viene eseguito quanto segue:

  • Disattiva l'animazione di sistema per il gesto Indietro predittivo.
  • Ignora OnBackInvokedCallback, ma le chiamate OnBackPressedCallback continuano a funzionare.

Attivare la funzionalità a livello di attività

A partire da Android 14, il flag android:enableOnBackInvokedCallback consente di attivare le animazioni di sistema predittive a livello di attività. Questo comportamento semplifica la migrazione di app multi-attività di grandi dimensioni ai gesti di scorrimento prevedibili. Con Android 15, il pulsante Indietro predittivo non è più nascosto dietro l'opzione per gli sviluppatori. Le app possono attivare la funzionalità predittiva completa o a livello di attività.

Il seguente codice mostra un esempio di utilizzo di enableOnBackInvokedCallback per attivare l'animazione di sistema di ritorno alla home page da MainActivity:

<manifest ...>
    <application . . .

        android:enableOnBackInvokedCallback="false">

        <activity
            android:name=".MainActivity"
            android:enableOnBackInvokedCallback="true"
            ...
        </activity>
        <activity
            android:name=".SecondActivity"
            android:enableOnBackInvokedCallback="false"
            ...
        </activity>
    </application>
</manifest>

Nell'esempio precedente, l'impostazione di android:enableOnBackInvokedCallback=true per ".SecondActivity" consente di attivare l'animazione di sistema cross-activity.

Quando utilizzi il flag android:enableOnBackInvokedCallback, tieni presente le seguenti considerazioni:

  • L'impostazione android:enableOnBackInvokedCallback=false disattiva le animazioni di scambio di app predittive a livello di attività o di app, a seconda di dove viene impostato il tag, e indica al sistema di ignorare le chiamate all'API di piattaforma OnBackInvokedCallback. Tuttavia, le chiamate a OnBackPressedCallback continuano a essere eseguite perché OnBackPressedCallback è compatibile con le versioni precedenti e chiama l'API onBackPressed, che non è supportata prima di Android 13.
  • L'impostazione del flag enableOnBackInvokedCallback a livello di app stabilisce il valore predefinito per tutte le attività nell'app. Puoi sostituire il valore predefinito in base all'attività impostando il flag a livello di attività, come mostrato nell'esempio di codice precedente.

Best practice per il callback

Di seguito sono riportate le best practice per utilizzare i callback di sistema supportati: BackHandler (per Compose), OnBackPressedCallback o OnBackInvokedCallback.

Determina lo stato dell'interfaccia utente che abilita e disabilita ogni callback

Lo stato dell'interfaccia utente è una proprietà che descrive l'interfaccia utente. Ti consigliamo di seguire questi passaggi di alto livello.

  1. Determina lo stato dell'interfaccia utente che attiva e disattiva ogni callback.

  2. Definisci lo stato utilizzando un tipo di titolare dei dati osservabile, ad esempio StateFlow o Scrivi stato e abilita o disabilita il callback quando lo stato cambia.

Se in precedenza la tua app associava la logica di ritorno a istruzioni condizionali, potrebbe significare che stai reagendo all'evento di ritorno dopo che è già avvenuto. Evita questo pattern con i callback più recenti. Se possibile, sposta il callback al di fuori dell'istruzione condizionale e associa invece il callback a un tipo di titolare dei dati osservabile.

Usa i callback del sistema per la logica UI

La logica dell'interfaccia utente prescrive come visualizzare l'interfaccia utente. Utilizza i callback del sistema per eseguire la logica dell'interfaccia utente, ad esempio per visualizzare un popup o eseguire un'animazione.

Se la tua app attiva un callback Indietro di sistema, le animazioni predittive non vengono eseguite e devi gestire l'evento Indietro. Non creare callback solo per eseguire logica non UI.

Ad esempio, se intercetti gli eventi di ritorno solo per registrarli, registrali invece nel ciclo di vita dell'attività o del frammento.

  • Per i casi di transizione da attività ad attività o da frammento ad attività, registra se isFinishing in onDestroy è true nel ciclo di vita dell'attività.
  • Per i casi da frammento a frammento, registra se isRemoving in onDestroy è true all'interno del ciclo di vita della vista frammento. In alternativa, registra utilizzando i metodi onBackStackChangeStarted o onBackStackChangeCommitted all'interno di FragmentManager.OnBackStackChangedListener.

Per la richiesta Componi, registra il log all'interno del callback onCleared() di un ViewModel associato alla destinazione Componi. Questo è l'indicatore migliore per sapere quando una destinazione di composizione viene rimossa dallo stack precedente e distrutta.

Creare callback con una sola responsabilità

Puoi aggiungere più callback al gestore. I callback vengono aggiunti a un mucchio in cui l'ultimo callback abilitato aggiunto gestisce il gesto Indietro successivo con un callback per gesto Indietro.

È più facile gestire lo stato abilitato di un callback se questo ha una sola responsabilità. Ad esempio:

Ordine dei callback in uno stack.
Figura 2. Diagramma dello stack di callback.

La Figura 2 mostra come puoi avere più callback nello stack, ognuno responsabile di una cosa. Un callback viene eseguito solo se i callback precedenti nello stack sono disabilitati. In questo esempio, il callback "Sei sicuro…" viene attivato quando l'utente inserisce dati in un modulo e disattivato in caso contrario. Il callback apre una finestra di dialogo di conferma quando l'utente scorre verso il retro per uscire dal form.

L'altro callback può includere un componente Material che supporta il riavvolgimento predittivo, una transizione AndroidX che utilizza le API Progress o un altro callback personalizzato.

Il callback di childFragmentManager viene eseguito se i callback precedenti sono disabilitati e il back stack per questo FragmentManager non è vuoto, dove childFragmentManager è collegato all'interno di un Frammento. In questo esempio, questo callback interno è disattivato.

Analogamente, il callback interno di supportFragmentManager viene eseguito se i callback precedenti sono disattivati e la relativa pila non è vuota. Questo comportamento è coerente quando si utilizza FragmentManager o NavigationComponent per la navigazione, poiché NavigationComponent si basa su FragmentManager. In questo esempio, questo callback viene eseguito se l'utente non ha inserito del testo nel modulo, causando la disattivazione del callback "Sei sicuro…".

Infine, super.onBackPressed()è il callback a livello di sistema, che viene eseguito di nuovo se i callback precedenti sono disattivati. Per attivare le animazioni di sistema come il ritorno alla home page, le animazioni tra attività e tra attività, la pila di supportFragmentManager deve essere vuota, quindi il suo callback interno deve essere disattivato.

Testare l'animazione del gesto Indietro predittivo

Se utilizzi ancora Android 13 o Android 14, puoi testare l'animazione di ritorno alla casa mostrata in Figura 1.

Per testare questa animazione, completa i seguenti passaggi:

  1. Sul dispositivo, vai a Impostazioni > Sistema > Opzioni sviluppatore.

  2. Seleziona Animazioni Indietro predittive.

  3. Avvia l'app aggiornata e usa il gesto Indietro per vederla in azione.