Fornisci una navigazione a ritroso personalizzata

La navigazione a ritroso indica il modo in cui gli utenti tornano indietro nella cronologia delle schermate visitate in precedenza. Tutti i dispositivi Android offrono un pulsante Indietro per questo tipo di navigazione, pertanto non dovresti aggiungere un pulsante Indietro all'interfaccia utente dell'app. A seconda del dispositivo Android dell'utente, questo pulsante potrebbe essere fisico o software.

Android mantiene uno stack posteriore di destinazioni mentre l'utente naviga nell'applicazione. In genere questo consente ad Android di raggiungere correttamente le destinazioni precedenti quando si preme il pulsante Indietro. Tuttavia, in alcuni casi, la tua app potrebbe dover implementare il proprio comportamento Indietro per offrire la migliore esperienza utente possibile. Ad esempio, quando utilizzi un WebView, è possibile che tu voglia ignorare il comportamento predefinito del pulsante Indietro per consentire all'utente di tornare indietro nella cronologia di navigazione web anziché nelle schermate precedenti dell'app.

Implementare la navigazione a ritroso personalizzata

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

OnBackPressedDispatcher controlla il modo in cui gli eventi del pulsante Indietro vengono inviati a uno o più oggetti OnBackPressedCallback. Il costruttore di OnBackPressedCallback utilizza un valore booleano per lo stato iniziale abilitato. Solo quando è attivato un callback (ad es. isEnabled() restituisce true) il supervisore chiamerà il callback handleOnBackPressed() per gestire l'evento del pulsante Indietro. Puoi modificare lo stato attivo chiamando setEnabled().

I callback vengono aggiunti tramite i metodi addCallback. Ti consigliamo vivamente di utilizzare 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 viene eliminato l'elemento LifecycleOwner associato, il che impedisce perdite di memoria e la rende adatta all'utilizzo in frammenti o altri proprietari del ciclo di vita con una durata più breve dell'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 tramite addCallback(). In questo caso, i callback vengono attivati nell'ordine inverso in cui vengono aggiunti: il callback aggiunto per ultimo è il primo che ha la possibilità di gestire l'evento del pulsante Indietro. Ad esempio, se aggiungi tre callback denominati one, two e three in ordine, questi verranno richiamati nell'ordine rispettivamente di three, two e one.

I callback seguono il pattern di catena di responsabilità. Ogni callback nella catena viene richiamato solo se il callback precedente non è stato abilitato. Ciò significa che nell'esempio precedente, il callback two veniva richiamato solo se il callback three non era attivato. La richiamata one viene richiamata solo se il callback two non è stato abilitato e così via.

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

Ti consigliamo di cambiare lo stato abilitato in OnBackPressedCallback per le modifiche temporanee, in quanto mantiene l'ordine descritto sopra, il che è particolarmente importante se hai callback registrati su più proprietari nidificati del ciclo di vita.

Tuttavia, nei casi in cui vuoi rimuovere completamente OnBackPressedCallback, devi chiamare remove(). Tuttavia, questa operazione di solito non è necessaria, perché i callback vengono rimossi automaticamente quando l'elemento LifecycleOwner associato viene eliminato.

Attività onBackPressed()

Se utilizzi onBackPressed() per gestire gli eventi del pulsante Indietro, ti consigliamo di utilizzare invece un OnBackPressedCallback. Tuttavia, se non riesci ad apportare questa modifica, vengono applicate le seguenti regole:

  • Tutte le richiamate registrate tramite addCallback vengono valutate quando chiami super.onBackPressed().
  • In Android 12 (livello API 32) e versioni precedenti, onBackPressed viene sempre chiamato, indipendentemente dalle istanze registrate di OnBackPressedCallback.