Fournir un retour arrière personnalisé

Le retour arrière permet aux utilisateurs de revenir en arrière dans l'historique des écrans qu'ils ont déjà consultés. Tous les appareils Android proposent un bouton "Retour" pour ce type de navigation. Vous ne devez donc pas ajouter de bouton "Retour" à l'interface utilisateur de votre application. Selon l'appareil Android de l'utilisateur, ce bouton peut être un bouton physique ou un bouton logiciel.

Android conserve une pile "Retour" des destinations à mesure que l'utilisateur parcourt votre application. Cela permet généralement à Android de naviguer correctement vers les destinations précédentes en appuyant sur le bouton "Retour". Toutefois, dans certains cas, il se peut que votre application doive implémenter son propre comportement "Retour" afin d'offrir la meilleure expérience utilisateur possible. Par exemple, lorsque vous utilisez une WebView, vous pouvez ignorer le comportement par défaut du bouton "Retour" pour permettre à l'utilisateur de revenir dans son historique de navigation Web plutôt que dans les écrans précédents de votre application.

Implémenter un retour arrière personnalisé

ComponentActivity, la classe de base pour FragmentActivity et AppCompatActivity, permet de contrôler le comportement du bouton "Retour" à l'aide de son OnBackPressedDispatcher, que vous pouvez récupérer en appelant getOnBackPressedDispatcher().

OnBackPressedDispatcher contrôle la façon dont les événements du bouton "Retour" sont envoyés à un ou plusieurs objets OnBackPressedCallback. Le constructeur de OnBackPressedCallback utilise une valeur booléenne pour l'état initial activé. C'est seulement quand un rappel est activé (isEnabled() renvoie la valeur true) que le dispatcher appelle la méthode handleOnBackPressed() du rappel pour gérer l'événement du bouton "Retour". Vous pouvez modifier l'état d'activation en appelant setEnabled().

Les rappels sont ajoutés via les méthodes addCallback. Il est vivement recommandé d'utiliser la méthode addCallback(), qui accepte un LifecycleOwner. Cela vous aide à assurer que OnBackPressedCallback n'est ajouté que lorsque LifecycleOwner est défini sur Lifecycle.State.STARTED. L'activité supprime également les rappels enregistrés lorsque le LifecycleOwner associé est détruit. Cela permet d'éviter les fuites de mémoire et de les utiliser dans des fragments ou d'autres propriétaires de cycle de vie ayant une durée de vie plus courte.

Voici un exemple d'implémentation du rappel :

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()
    }
    ...
}

Vous pouvez fournir plusieurs rappels via addCallback(). Les rappels sont alors appelés dans l'ordre inverse dans lequel ils sont ajoutés. Le rappel ajouté en dernier est le premier à avoir la possibilité de gérer l'événement du bouton "Retour". Par exemple, si vous avez ajouté trois rappels nommés one, two et three dans l'ordre, ils seront appelés dans l'ordre three, two, et one, respectivement.

Les rappels suivent le schéma de chaîne de responsabilité. Chaque rappel de la chaîne n'est invoqué que si le rappel précédent n'a pas été activé. Cela signifie que dans l'exemple précédent, le rappel two ne sera invoqué que si le rappel three n'est pas activé. Le rappel one ne serait invoqué que si le rappel two n'était pas activé, et ainsi de suite.

Notez qu'une fois ajouté via addCallback(), le rappel n'est pas ajouté à la chaîne de responsabilité tant que LifecycleOwner n'est pas à l'état Lifecycle.State.STARTED.

Il est fortement recommandé de modifier l'état d'activation de OnBackPressedCallback pour les modifications temporaires, car cela conserve l'ordre décrit ci-dessus, ce qui est particulièrement important si vous avez enregistré des rappels pour plusieurs propriétaires de cycle de vie imbriqués différents.

Toutefois, si vous souhaitez supprimer entièrement OnBackPressedCallback, vous devez appeler remove(). Ce n'est généralement pas nécessaire, car les rappels sont automatiquement supprimés lorsque leur LifecycleOwner associé est détruit.

Activité onBackPressed()

Si vous utilisez onBackPressed() pour gérer les événements du bouton "Retour", nous vous recommandons d'utiliser plutôt OnBackPressedCallback. Toutefois, si vous ne parvenez pas à effectuer cette modification, les règles suivantes s'appliquent :

  • Tous les rappels enregistrés via addCallback sont évalués lorsque vous appelez super.onBackPressed().
  • Dans Android 12 (niveau d'API 32) et versions antérieures, onBackPressed est toujours appelé, quelles que soient les instances enregistrées de OnBackPressedCallback.