Fornisci una navigazione a ritroso personalizzata

Gli utenti navigano all'indietro tra le schermate utilizzando la navigazione indietro. La maggior parte dei dispositivi Android ha un pulsante Indietro fisico, software o basato su gesti. In genere, non devi aggiungere un pulsante Indietro alla tua app. Tuttavia, i dispositivi Android Automotive OS (AAOS) in modalità compatibilità utilizzano un pulsante Indietro di sistema. Gestisce la navigazione, quindi non devi aggiungerne una tua. Per maggiori dettagli, vedi Modalità di compatibilità AAOS.

Android gestisce uno stack indietro delle destinazioni mentre l'utente naviga nell'applicazione. In genere, ciò consente ad Android di navigare correttamente nelle destinazioni precedenti quando viene premuto il pulsante Indietro. Tuttavia, in alcuni casi la tua app potrebbe dover implementare un proprio comportamento Indietro per offrire la migliore esperienza utente possibile. Ad esempio, quando utilizzi un WebView, potresti voler ignorare il comportamento predefinito del pulsante Indietro per consentire all'utente di navigare nella cronologia di navigazione web anziché nelle schermate precedenti della tua app.

Implementare la navigazione indietro personalizzata in Compose

In Jetpack Compose, puoi gestire la navigazione indietro personalizzata utilizzando il composable BackHandler.

Quando utilizzi Navigation Compose, in genere utilizzi NavController.navigateUp() o NavController.popBackStack() per passare alla schermata precedente nello stack indietro. Tuttavia, BackHandler è utile nei casi in cui vuoi implementare un comportamento personalizzato quando l'utente preme il pulsante Indietro del sistema o utilizza il gesto Indietro. Ad esempio, se visualizzi un WebView nella tua app, potresti voler consentire agli utenti di tornare indietro nella cronologia di navigazione quando premono il pulsante Indietro del sistema.

Se hai più componibili BackHandler attivati a diversi livelli dell'albero dei componibili, solo quello più interno intercetta l'evento Indietro.

Implementare la navigazione indietro personalizzata con Views

ComponentActivity, la classe base per FragmentActivity e AppCompatActivity, ti consente di controllare il comportamento del pulsante Indietro utilizzando il relativo OnBackPressedDispatcher, che puoi recuperare chiamando getOnBackPressedDispatcher().

OnBackPressedDispatcher controlla la modalità di invio degli eventi del pulsante Indietro a uno o più oggetti OnBackPressedCallback. Il costruttore per OnBackPressedCallback accetta un valore booleano per lo stato di attivazione iniziale. Solo quando un callback è abilitato, ad esempio quando isEnabled() restituisce true, il dispatcher chiama handleOnBackPressed() del callback per gestire l'evento del pulsante Indietro. Puoi modificare lo stato di attivazione chiamando il numero setEnabled().

I callback vengono aggiunti utilizzando i metodi addCallback. Utilizza il metodo addCallback(), che richiede un LifecycleOwner. In questo modo, OnBackPressedCallback viene aggiunto solo quando LifecycleOwner è Lifecycle.State.STARTED. L'attività rimuove anche i callback registrati quando il relativo LifecycleOwner viene eliminato, il che impedisce perdite di memoria e lo rende adatto all'uso in fragment o altri proprietari del ciclo di vita con una durata inferiore rispetto all'attività.

Ecco un esempio di implementazione del callback:

Kotlin

class MyFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // This callback will only be called when MyFragment is at least Started.
        val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
            // Handle the back button event
        }

        // The callback can be enabled or disabled here or in the lambda
    }
    ...
}

Java

public class MyFragment extends Fragment {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // This callback will only be called when MyFragment is at least Started.
        OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) {
            @Override
            public void handleOnBackPressed() {
                // Handle the back button event
            }
        };
        requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);

        // The callback can be enabled or disabled here or in handleOnBackPressed()
    }
    ...
}

Puoi fornire più callback utilizzando addCallback(). In questo modo, i callback vengono richiamati nell'ordine inverso in cui sono stati aggiunti: il callback aggiunto per ultimo è il primo a cui viene data la possibilità di gestire l'evento del pulsante Indietro. Ad esempio, se hai aggiunto tre callback denominati one, two e three in ordine, verranno richiamati nell'ordine three, two e one, rispettivamente.

I callback seguono il pattern Chain of Responsibility. Ogni callback nella catena viene richiamato solo se il callback precedente non è stato attivato. Ciò significa che nell'esempio precedente, il callback two verrà richiamato solo se il callback three non è stato abilitato. Il callback one verrà richiamato solo se il callback two non è stato abilitato e così via.

Tieni presente che quando viene aggiunto utilizzando addCallback(), il callback non viene aggiunto alla catena di responsabilità finché LifecycleOwner non entra nello stato Lifecycle.State.STARTED.

La modifica dello stato di attivazione in OnBackPressedCallback è fortemente consigliata per le modifiche temporanee, in quanto mantiene l'ordinamento descritto sopra, il che è particolarmente importante se hai callback registrati su più proprietari del ciclo di vita nidificati diversi.

Tuttavia, nei casi in cui vuoi rimuovere completamente OnBackPressedCallback, devi chiamare remove(). Di solito non è necessario, perché i callback vengono rimossi automaticamente quando il relativo LifecycleOwner viene eliminato.