Benutzerdefinierte Zurück-Navigation bereitstellen

Nutzer navigieren mit der Zurück-Navigation durch die Bildschirme. Die meisten Android-Geräte haben eine Zurück-Schaltfläche – physisch, softwarebasiert oder per Geste. Normalerweise sollten Sie Ihrer App keine Schaltfläche „Zurück“ hinzufügen. Auf Android Automotive OS-Geräten (AAOS) im Kompatibilitätsmodus wird jedoch eine Systemschaltfläche „Zurück“ verwendet. Die Navigation wird automatisch übernommen, sodass Sie keine eigene hinzufügen müssen. Weitere Informationen finden Sie unter AAOS-Kompatibilitätsmodus.

Android verwaltet einen Backstack von Zielen, während der Nutzer durch Ihre Anwendung navigiert. Dadurch kann Android in der Regel richtig zu vorherigen Zielen zurückkehren, wenn die Schaltfläche „Zurück“ gedrückt wird. Es gibt jedoch einige Fälle, in denen Ihre App ihr eigenes „Zurück“-Verhalten implementieren muss, um eine optimale Nutzerfreundlichkeit zu bieten. Wenn Sie beispielsweise ein WebView verwenden, möchten Sie möglicherweise das Standardverhalten der Schaltfläche „Zurück“ überschreiben, damit der Nutzer durch seinen Webbrowserverlauf statt durch die vorherigen Bildschirme in Ihrer App zurückgehen kann.

Benutzerdefinierte Rückwärtsnavigation in Compose implementieren

In Jetpack Compose können Sie die benutzerdefinierte Zurück-Navigation mit der Composable BackHandler verarbeiten.

Wenn Sie Navigation Compose verwenden, navigieren Sie in der Regel mit NavController.navigateUp() oder NavController.popBackStack() zum vorherigen Bildschirm im Backstack. BackHandler ist jedoch nützlich, wenn Sie benutzerdefiniertes Verhalten implementieren möchten, wenn der Nutzer die System-Schaltfläche „Zurück“ drückt oder die Touch-Geste „Zurück“ verwendet. Wenn Sie beispielsweise ein WebView in Ihrer App anzeigen, möchten Sie möglicherweise, dass Nutzer durch den Browserverlauf zurückgehen können, wenn sie die System-Zurück-Schaltfläche drücken.

Wenn Sie mehrere aktivierte BackHandler-Composables auf verschiedenen Ebenen Ihres Composable-Baums haben, fängt nur die innerste das Zurück-Ereignis ab.

Benutzerdefinierte Zurück-Navigation mit Views implementieren

ComponentActivity, die Basisklasse für FragmentActivity und AppCompatActivity, ermöglicht es Ihnen, das Verhalten der Schaltfläche „Zurück“ mit der OnBackPressedDispatcher zu steuern, die Sie durch Aufrufen von getOnBackPressedDispatcher() abrufen können.

Mit OnBackPressedDispatcher wird gesteuert, wie Ereignisse der Zurück-Schaltfläche an ein oder mehrere OnBackPressedCallback-Objekte gesendet werden. Der Konstruktor für OnBackPressedCallback akzeptiert einen booleschen Wert für den anfänglichen aktivierten Status. Nur wenn ein Callback aktiviert ist, z. B. wenn isEnabled() true zurückgibt, ruft der Dispatcher den handleOnBackPressed()-Callback auf, um das Ereignis der Zurück-Schaltfläche zu verarbeiten. Sie können den aktivierten Status ändern, indem Sie setEnabled() aufrufen.

Rückrufe werden mit den addCallback-Methoden hinzugefügt. Verwenden Sie die Methode addCallback(), die ein LifecycleOwner akzeptiert. So wird der OnBackPressedCallback nur hinzugefügt, wenn der LifecycleOwner Lifecycle.State.STARTED ist. Bei der Aktivität werden auch registrierte Rückrufe entfernt, wenn der zugehörige LifecycleOwner zerstört wird. Dadurch werden Speicherlecks verhindert und die Aktivität kann in Fragmenten oder anderen Lifecycle-Inhabern mit einer kürzeren Lebensdauer als die Aktivität verwendet werden.

Hier ein Beispiel für die Implementierung eines Rückrufs:

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

Sie können mehrere Callbacks mit addCallback() angeben. Die Callbacks werden in der umgekehrten Reihenfolge aufgerufen, in der sie hinzugefügt wurden. Der zuletzt hinzugefügte Callback erhält als Erstes die Möglichkeit, das Ereignis der Zurück-Schaltfläche zu verarbeiten. Wenn Sie beispielsweise drei Callbacks mit den Namen one, two und three in dieser Reihenfolge hinzugefügt haben, werden sie in der Reihenfolge three, two und one aufgerufen.

Callbacks folgen dem Muster Chain of Responsibility. Jeder Callback in der Kette wird nur aufgerufen, wenn der vorherige Callback nicht aktiviert wurde. Das bedeutet, dass im vorherigen Beispiel der Callback two nur aufgerufen würde, wenn der Callback three nicht aktiviert ist. Der Callback one wird nur aufgerufen, wenn der Callback two nicht aktiviert ist usw.

Wenn der Callback mit addCallback() hinzugefügt wird, wird er erst dann in die Chain of Responsibility aufgenommen, wenn LifecycleOwner den Status Lifecycle.State.STARTED erreicht.

Das Ändern des aktivierten Status für OnBackPressedCallback wird für temporäre Änderungen dringend empfohlen, da die oben beschriebene Reihenfolge beibehalten wird. Das ist besonders wichtig, wenn Sie Callbacks für mehrere verschiedene verschachtelte Lifecycle-Inhaber registriert haben.

Wenn Sie OnBackPressedCallback jedoch vollständig entfernen möchten, sollten Sie remove() aufrufen. Das ist in der Regel jedoch nicht erforderlich, da Callbacks automatisch entfernt werden, wenn das zugehörige LifecycleOwner zerstört wird.