Aggiunta del supporto per il gesto Indietro predittivo

Figura 1. Simulazione dell'aspetto predittivo del gesto Indietro su uno smartphone

Android 14 (livello API 34) aggiunge il supporto per ulteriori animazioni di sistema e API per creare animazioni personalizzate. Per maggiori informazioni, consulta Aggiungere il supporto per animazioni Indietro predittive integrate e personalizzate.

Ad esempio, se utilizzi un gesto Indietro puoi visualizzare un'anteprima animata della schermata Home dietro l'app, come presentata nel modello nella Figura 1. A partire da Android 13, puoi testare questa animazione per il rientro a casa attivando un'opzione sviluppatore (come descritto in questa pagina).

Il supporto del gesto Indietro predittivo richiede l'aggiornamento dell'app, utilizzando l'API OnBackPressedCallback AppCompat 1.6.0-alpha05 (AndroidX) o versioni successive compatibile con le versioni precedenti oppure la nuova API della piattaforma OnBackInvokedCallback. La maggior parte delle app userà l'API AndroidX compatibile con le versioni precedenti.

Questo aggiornamento fornisce un percorso di migrazione per intercettare correttamente la navigazione a ritroso, il che comporta 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 Indietro del sistema.

Codelab e video su Google I/O

Oltre a utilizzare la documentazione in questa pagina, prova il nostro codelab. Fornisce un'implementazione comune di un componente WebView che gestisce il gesto Indietro predittivo utilizzando le API AndroidX Activity.

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

Aggiornare un'app che utilizza la navigazione a ritroso predefinita

L'aggiornamento dell'app per supportare questa funzionalità è semplice se l'app non implementa alcun comportamento arretrato personalizzato (in altre parole, lascia la gestione al sistema). Attiva questa funzionalità come descritto in questa guida.

Se la tua app utilizza Frammenti o il componente di navigazione, esegui anche l'upgrade ad 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 Indietro personalizzato, i percorsi di migrazione saranno diversi a seconda che venga utilizzata o meno AndroidX e come gestisce la navigazione a ritroso.

La tua app utilizza AndroidX In che modo l'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 delle piattaforme non supportate Eseguire la migrazione alle API AndroidX di un'app AndroidX contenente API di navigazione a ritroso non supportate
No API delle piattaforme non supportate, in grado di eseguire la migrazione Eseguire la migrazione di un'app che utilizza API di navigazione posteriore non supportate alle API della piattaforma
API delle piattaforme non supportate, ma impossibile eseguire la migrazione Posticipa l'attivazione finché non diventerà 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 tramite gesti personalizzata con OnBackPressedDispatcher, come descritto in Fornire una navigazione indietro 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 Frammenti e il componente di navigazione) funzionino perfettamente con il gesto Indietro predittivo, esegui l'upgrade all'Attività di AndroidX 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.

Esegui la migrazione di un'app AndroidX che contiene 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 della parte posteriore del sistema a OnBackPressedDispatcher di AndroidX con un'implementazione di OnBackPressedCallback. Per indicazioni dettagliate, vedi Fornire una navigazione a ritroso personalizzata.

  2. Disabilita 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 ad 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. Una volta eseguita correttamente la migrazione dell'app, attiva il gesto Indietro predittivo (come descritto in questa pagina) per visualizzare l'animazione del sistema per tornare alla home page.

Eseguire la migrazione alle API della piattaforma di un'app che utilizza API di navigazione posteriore non supportate

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

Completa i seguenti passaggi per eseguire la migrazione delle API non supportate all'API della piattaforma:

  1. Utilizza la nuova API OnBackInvokedCallback sui dispositivi con Android 13 o versioni successive e utilizza 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à corrente non viene completata e il callback ha la possibilità di reagire all'azione Indietro una volta che l'utente ha completato la navigazione Indietro del sistema.

  3. Annulla la registrazione di OnBackInvokedCallback quando vuoi interrompere l'intercettazione del gesto Indietro. In caso contrario, gli utenti potrebbero notare comportamenti indesiderati quando utilizzano una navigazione a ritroso del sistema, ad esempio "rimanere bloccati" tra una visualizzazione e l'altra e costringerli a forzare l'uscita 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 a ritroso tramite OnBackPressed o KeyEvent.KEYCODE_BACK per Android 13 e versioni successive.

  5. Una volta eseguita correttamente la migrazione dell'app, attiva il gesto Indietro predittivo (come descritto in questa pagina) in modo che OnBackInvokedCallback abbia effetto.

Puoi registrare un OnBackInvokedCallback con PRIORITY_DEFAULT o PRIORITY_OVERLAY, che non è disponibile nell'AndroidX simile OnBackPressedCallback. In alcuni casi, la registrazione di un callback con PRIORITY_OVERLAY è utile. Questo potrebbe accadere quando esegui la migrazione da onKeyPreIme() e il callback deve ricevere il gesto Indietro invece di un IME aperto. Gli IME registrano i callback con PRIORITY_DEFAULT all'apertura. 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 Indietro predittivo.

Per l'attivazione, in AndroidManifest.xml, nel tag <application> imposta il flag android:enableOnBackInvokedCallback su true.

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

Se non specifichi un valore, il valore predefinito è false e:

  • Disattiva l'animazione di sistema dei gesti Indietro predittivi.
  • Ignora OnBackInvokedCallback, ma le chiamate OnBackPressedCallback continuano a funzionare.

Attivazione a livello di attività

A partire da Android 14, il flag android:enableOnBackInvokedCallback ti consente di attivare le animazioni di sistema predittive a livello di attività. Questo comportamento rende più gestibile la migrazione di app multiattività di grandi dimensioni ai gesti Indietro predittivi.

Il codice seguente mostra un esempio di utilizzo di enableOnBackInvokedCallback per attivare l'animazione del sistema per il rientro a casa 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 di android:enableOnBackInvokedCallback=false disattiva le animazioni predittive a livello di attività o di app, a seconda di dove imposti il tag, e indica al sistema di ignorare le chiamate all'API della 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 UI è una proprietà che descrive l'interfaccia utente. Ti consigliamo di seguire questi passaggi generali.

  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 l'app associava la logica dorsale ad istruzioni condizionali, questo potrebbe significare che stai reagendo all'evento back dopo che si è già verificato, un pattern che dovresti evitare 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 UI indica come visualizzare la UI. Utilizza i callback del sistema per eseguire la logica dell'interfaccia utente, ad esempio per visualizzare un popup o eseguire un'animazione.

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

Ad esempio, se gli eventi vengono intercettati solo per il log, accedi invece al ciclo di vita Attività o Frammento.

  • Per i casi da attività ad attività o da frammento ad attività, registra se isFinishing in onDestroy è true durante il 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; oppure registra utilizzando i metodi onBackStackChangeStarted o onBackStackChangeCommitted in FragmentManager.OnBackStackChangedListener.

Per la richiesta Compose, accedi al callback onCleared() di un ViewModel associato alla destinazione Compose. Questo è il segnale migliore per sapere quando una destinazione di composizione è stata rimossa e distrutta.

Crea callback di responsabilità singola

Questo è possibile perché puoi aggiungere più callback al supervisore. I callback vengono aggiunti a una serie in cui l'ultimo callback attivato aggiunto gestisce il gesto Indietro successivo con un callback per ogni gesto Indietro.

Testa l'animazione del gesto Indietro predittivo

A partire dalla release finale di Android 13, dovresti essere in grado di abilitare un'opzione per sviluppatori per testare l'animazione per il rientro a casa mostrata nella Figura 1.

Per testare questa animazione, procedi nel seguente modo:

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

  2. Seleziona Animazioni predittive per il retro.

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