UI-Komponenten über NavigationUI mit NavController verbinden

Die Navigationskomponente enthält eine NavigationUI-Klasse. Diese Klasse enthält statische Methoden, die die Navigation über die obere App-Leiste, die Navigationsleiste und die Navigation am unteren Rand verwalten.

Obere App-Leiste

Die obere App-Leiste bietet einen einheitlichen Bereich oben in deiner App, an dem Informationen und Aktionen vom aktuellen Bildschirm angezeigt werden.

Bildschirm mit einer oberen App-Leiste
Abbildung 1: Ein Bildschirm mit einer oberen App-Leiste.

NavigationUI enthält Methoden, mit denen Inhalte in der oberen App-Leiste automatisch aktualisiert werden, wenn Nutzer durch Ihre App navigieren. NavigationUI verwendet beispielsweise die Ziellabels aus Ihrer Navigationsgrafik, um den Titel der oberen App-Leiste auf dem neuesten Stand zu halten.

<navigation>
    <fragment ...
              android:label="Page title">
      ...
    </fragment>
</navigation>

Wenn Sie NavigationUI mit den unten beschriebenen Implementierungen der oberen App-Leiste verwenden, kann das Label, das Sie an die Ziele anhängen, automatisch aus den für das Ziel bereitgestellten Argumenten mit dem Format {argName} in Ihrem Label ausgefüllt werden.

NavigationUI unterstützt die folgenden oberen Arten von App-Leisten:

Weitere Informationen zu App-Leisten finden Sie unter App-Leiste einrichten.

AppBar-Konfiguration

NavigationUI verwendet ein AppBarConfiguration-Objekt, um das Verhalten der Navigationsschaltfläche links oben im Anzeigebereich Ihrer App zu verwalten. Das Verhalten der Navigationsschaltfläche ändert sich abhängig davon, ob sich der Nutzer an einem Ziel der obersten Ebene befindet.

Ein Ziel der obersten Ebene ist der Stamm oder das Ziel auf der höchsten Ebene in einer Reihe hierarchisch verbundener Ziele. Für Ziele auf oberster Ebene wird in der oberen App-Leiste keine Schaltfläche „Nach oben“ angezeigt, da es kein übergeordnetes Ziel gibt. Standardmäßig ist das Startziel der App das einzige Ziel auf oberster Ebene.

Wenn sich der Nutzer an einem Ziel auf oberster Ebene befindet, wird die Navigationsschaltfläche zu einem Schubladensymbol , wenn für das Ziel ein DrawerLayout verwendet wird. Wird für das Ziel kein DrawerLayout verwendet, ist die Navigationsschaltfläche ausgeblendet. Wenn sich der Nutzer an einem anderen Ziel befindet, wird die Navigationsschaltfläche als Nach-oben-Schaltfläche angezeigt. Wenn Sie die Navigationsschaltfläche so konfigurieren möchten, dass nur das Startziel als Ziel auf oberster Ebene verwendet wird, erstellen Sie ein AppBarConfiguration-Objekt und übergeben Sie das entsprechende Navigationsdiagramm, wie unten dargestellt:

Kotlin

val appBarConfiguration = AppBarConfiguration(navController.graph)

Java

AppBarConfiguration appBarConfiguration =
        new AppBarConfiguration.Builder(navController.getGraph()).build();

In einigen Fällen müssen Sie möglicherweise mehrere Ziele auf oberster Ebene definieren, anstatt das standardmäßige Startziel zu verwenden. Ein häufiger Anwendungsfall hierfür ist die Verwendung von BottomNavigationView. Hier kann es vorkommen, dass Sie gleichgeordnete Bildschirme haben, die nicht hierarchisch miteinander verbunden sind und jeweils eine eigene Gruppe verwandter Ziele haben. In solchen Fällen können Sie stattdessen eine Reihe von Ziel-IDs an den Konstruktor übergeben, wie unten gezeigt:

Kotlin

val appBarConfiguration = AppBarConfiguration(setOf(R.id.main, R.id.profile))

Java

AppBarConfiguration appBarConfiguration =
        new AppBarConfiguration.Builder(R.id.main, R.id.profile).build();

Symbolleiste erstellen

Um eine Symbolleiste mit NavigationUI zu erstellen, definiere zuerst die Leiste in deiner Hauptaktivität wie hier gezeigt:

<LinearLayout>
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar" />
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        ... />
    ...
</LinearLayout>

Rufen Sie als Nächstes setupWithNavController() über die onCreate()-Methode Ihrer Hauptaktivität auf, wie im folgenden Beispiel gezeigt:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    setContentView(R.layout.activity_main)

    ...

    val navController = findNavController(R.id.nav_host_fragment)
    val appBarConfiguration = AppBarConfiguration(navController.graph)
    findViewById<Toolbar>(R.id.toolbar)
        .setupWithNavController(navController, appBarConfiguration)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.activity_main);

    ...

    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    AppBarConfiguration appBarConfiguration =
            new AppBarConfiguration.Builder(navController.getGraph()).build();
    Toolbar toolbar = findViewById(R.id.toolbar);
    NavigationUI.setupWithNavController(
            toolbar, navController, appBarConfiguration);
}

Wenn die Navigationsschaltfläche für alle Ziele als Aufwärtsschaltfläche angezeigt werden soll, übergeben Sie beim Erstellen des AppBarConfiguration einen leeren Satz von Ziel-IDs für die Ziele auf oberster Ebene. Dies kann beispielsweise nützlich sein, wenn Sie eine zweite Aktivität haben, bei der für alle Ziele im Toolbar eine Schaltfläche „Nach oben“ angezeigt werden sollte. So kann der Nutzer zur übergeordneten Aktivität zurückkehren, wenn sich keine anderen Ziele im Back-Stack befinden. Mit setFallbackOnNavigateUpListener() können Sie das Fallback-Verhalten für den Fall steuern, dass navigateUp() sonst nichts tun würde, wie im folgenden Beispiel gezeigt:

Kotlin

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

    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    val appBarConfiguration = AppBarConfiguration(
        topLevelDestinationIds = setOf(),
        fallbackOnNavigateUpListener = ::onSupportNavigateUp
    )
    findViewById<Toolbar>(R.id.toolbar)
        .setupWithNavController(navController, appBarConfiguration)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...

    NavHostFragment navHostFragment = (NavHostFragment) supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder()
        .setFallbackOnNavigateUpListener(::onSupportNavigateUp)
        .build();
    Toolbar toolbar = findViewById(R.id.toolbar);
    NavigationUI.setupWithNavController(
            toolbar, navController, appBarConfiguration);
}

CollapsingToolbarLayout einschließen

Wenn Sie ein CollapsingToolbarLayout in Ihre Toolbar einbinden möchten, definieren Sie zuerst die Symbolleiste und das umgebende Layout in Ihrer Aktivität:

<LinearLayout>
    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/tall_toolbar_height">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleGravity="top"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"/>
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        ... />
    ...
</LinearLayout>

Rufen Sie als Nächstes setupWithNavController() über die onCreate-Methode Ihrer Hauptaktivität auf, wie unten gezeigt:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    setContentView(R.layout.activity_main)

    ...

    val layout = findViewById<CollapsingToolbarLayout>(R.id.collapsing_toolbar_layout)
    val toolbar = findViewById<Toolbar>(R.id.toolbar)
    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    val appBarConfiguration = AppBarConfiguration(navController.graph)
    layout.setupWithNavController(toolbar, navController, appBarConfiguration)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.activity_main);

    ...

    CollapsingToolbarLayout layout = findViewById(R.id.collapsing_toolbar_layout);
    Toolbar toolbar = findViewById(R.id.toolbar);
    NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    AppBarConfiguration appBarConfiguration =
            new AppBarConfiguration.Builder(navController.getGraph()).build();
    NavigationUI.setupWithNavController(layout, toolbar, navController, appBarConfiguration);
}

Aktionsleiste

Wenn Sie der Standardaktionsleiste Navigationsunterstützung hinzufügen möchten, rufen Sie setupActionBarWithNavController() über die onCreate()-Methode Ihrer Hauptaktivität auf, wie unten dargestellt. Sie müssen AppBarConfiguration außerhalb von onCreate() deklarieren, da Sie sie auch beim Überschreiben von onSupportNavigateUp() verwenden:

Kotlin

private lateinit var appBarConfiguration: AppBarConfiguration

...

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

    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    appBarConfiguration = AppBarConfiguration(navController.graph)
    setupActionBarWithNavController(navController, appBarConfiguration)
}

Java

AppBarConfiguration appBarConfiguration;

...

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...

    NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
    NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
}

Überschreiben Sie als Nächstes onSupportNavigateUp(), um die Nach-oben-Navigation zu verarbeiten:

Kotlin

override fun onSupportNavigateUp(): Boolean {
    val navController = findNavController(R.id.nav_host_fragment)
    return navController.navigateUp(appBarConfiguration)
            || super.onSupportNavigateUp()
}

Java

@Override
public boolean onSupportNavigateUp() {
    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    return NavigationUI.navigateUp(navController, appBarConfiguration)
            || super.onSupportNavigateUp();
}

App-Leistenvariationen unterstützen

Das Hinzufügen der oberen App-Leiste zu Ihrer Aktivität funktioniert gut, wenn das Layout der App-Leiste für jedes Ziel in Ihrer App ähnlich ist. Wenn sich die obere App-Leiste jedoch erheblich zwischen Zielen ändert, sollten Sie die obere App-Leiste aus Ihrer Aktivität entfernen und sie stattdessen in jedem Zielfragment definieren.

Beispielsweise kann eines Ihrer Ziele ein standardmäßiges Toolbar verwenden, während ein anderes ein AppBarLayout verwendet, um eine komplexere App-Leiste mit Tabs zu erstellen (siehe Abbildung 2).

Zwei Variationen der oberen App-Leiste: eine Standardsymbolleiste auf der linken Seite und ein App-Leistenlayout mit einer Symbolleiste und Tabs auf der rechten Seite
Abbildung 2: Zwei Varianten von App-Leisten. Links eine standardmäßige Toolbar. Rechts ein AppBarLayout mit Toolbar und Tabs.

Um dieses Beispiel in Ihren Zielfragmenten mithilfe von NavigationUI zu implementieren, definieren Sie zuerst die App-Leiste in jedem Ihrer Fragmentlayouts. Beginnen Sie mit dem Zielfragment, das eine Standardsymbolleiste verwendet:

<LinearLayout>
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        ... />
    ...
</LinearLayout>

Definieren Sie als Nächstes das Zielfragment, das eine App-Leiste mit Tabs verwendet:

<LinearLayout>
    <com.google.android.material.appbar.AppBarLayout
        ... />

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            ... />

        <com.google.android.material.tabs.TabLayout
            ... />

    </com.google.android.material.appbar.AppBarLayout>
    ...
</LinearLayout>

Die Logik der Navigationskonfiguration ist für beide Fragmente identisch, mit der Ausnahme, dass Sie setupWithNavController() in der onViewCreated()-Methode jedes Fragments aufrufen sollten, anstatt sie aus der Aktivität zu initialisieren:

Kotlin

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    val navController = findNavController()
    val appBarConfiguration = AppBarConfiguration(navController.graph)

    view.findViewById<Toolbar>(R.id.toolbar)
            .setupWithNavController(navController, appBarConfiguration)
}

Java

@Override
public void onViewCreated(@NonNull View view,
                          @Nullable Bundle savedInstanceState) {
    NavController navController = Navigation.findNavController(view);
    AppBarConfiguration appBarConfiguration =
            new AppBarConfiguration.Builder(navController.getGraph()).build();
    Toolbar toolbar = view.findViewById(R.id.toolbar);

    NavigationUI.setupWithNavController(
            toolbar, navController, appBarConfiguration);
}

Binden Sie Ziele mit Gerichten auf der Speisekarte zusammen.

NavigationUI bietet auch Hilfsprogramme zum Verknüpfen von Zielen mit menügesteuerten UI-Komponenten. NavigationUI enthält die Hilfsmethode onNavDestinationSelected(), die ein MenuItem zusammen mit dem NavController-Element verwendet, das das verknüpfte Ziel hostet. Wenn der id des MenuItem mit dem id des Ziels übereinstimmt, kann der NavController dieses Ziel aufrufen.

Die folgenden XML-Snippets definieren beispielsweise einen Menüpunkt und ein Ziel mit einem gemeinsamen id, details_page_fragment:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    ... >

    ...

    <fragment android:id="@+id/details_page_fragment"
         android:label="@string/details"
         android:name="com.example.android.myapp.DetailsFragment" />
</navigation>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    ...

    <item
        android:id="@+id/details_page_fragment"
        android:icon="@drawable/ic_details"
        android:title="@string/details" />
</menu>

Wenn Ihr Menü beispielsweise über den onCreateOptionsMenu() der Aktivität hinzugefügt wurde, können Sie die Menüelemente mit Zielen verknüpfen, indem Sie das onOptionsItemSelected() der Aktivität überschreiben, um onNavDestinationSelected() aufzurufen, wie im folgenden Beispiel gezeigt:

Kotlin

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    val navController = findNavController(R.id.nav_host_fragment)
    return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item)
}

Java

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    return NavigationUI.onNavDestinationSelected(item, navController)
            || super.onOptionsItemSelected(item);
}

Wenn ein Nutzer jetzt auf den Menüpunkt details_page_fragment klickt, gelangt die App automatisch zum entsprechenden Ziel mit derselben id.

Navigationsleiste hinzufügen

Die Navigationsleiste ist ein UI-Bereich, in dem das Hauptnavigationsmenü Ihrer App angezeigt wird. Die Leiste wird angezeigt, wenn der Nutzer das Leistensymbol in der App-Leiste berührt oder vom linken Rand des Bildschirms mit einem Finger wischt.

Eine offene Leiste mit einem Navigationsmenü
Abbildung 3: Eine offene Leiste mit einem Navigationsmenü.

Das Leistensymbol wird bei allen Zielen auf oberster Ebene angezeigt, die eine DrawerLayout verwenden.

Wenn Sie eine Navigationsleiste hinzufügen möchten, müssen Sie zuerst eine DrawerLayout als Stammansicht deklarieren. Fügen Sie im DrawerLayout ein Layout für den Hauptinhalt der UI und eine weitere Ansicht mit dem Inhalt der Navigationsleiste hinzu.

Im folgenden Layout wird beispielsweise ein DrawerLayout mit zwei untergeordneten Ansichten verwendet: NavHostFragment für den Hauptinhalt und NavigationView für den Inhalt der Navigationsleiste.

<?xml version="1.0" encoding="utf-8"?>
<!-- Use DrawerLayout as root container for activity -->
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <!-- Layout to contain contents of main body of screen (drawer will slide over this) -->
    <androidx.fragment.app.FragmentContainerView
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:id="@+id/nav_host_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />

    <!-- Container for contents of drawer - use NavigationView to make configuration easier -->
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true" />

</androidx.drawerlayout.widget.DrawerLayout>

Als Nächstes verbinden Sie DrawerLayout mit dem Navigationsdiagramm. Dazu übergeben Sie es an AppBarConfiguration, wie im folgenden Beispiel gezeigt:

Kotlin

val appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)

Java

AppBarConfiguration appBarConfiguration =
        new AppBarConfiguration.Builder(navController.getGraph())
            .setDrawerLayout(drawerLayout)
            .build();

Rufen Sie als Nächstes in Ihrer Hauptaktivitätsklasse setupWithNavController() über die onCreate()-Methode Ihrer Hauptaktivität auf, wie unten gezeigt:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    setContentView(R.layout.activity_main)

    ...

    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    findViewById<NavigationView>(R.id.nav_view)
        .setupWithNavController(navController)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.activity_main);

    ...

    NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    NavigationView navView = findViewById(R.id.nav_view);
    NavigationUI.setupWithNavController(navView, navController);
}

Ab Navigation 2.4.0-alpha01 wird der Status jedes Menüpunkts gespeichert und wiederhergestellt, wenn Sie setupWithNavController verwenden.

Navigation am unteren Rand

NavigationUI kann auch die Navigation am unteren Rand übernehmen. Wenn ein Nutzer einen Menüpunkt auswählt, ruft NavController onNavDestinationSelected() auf und aktualisiert das ausgewählte Element in der unteren Navigationsleiste automatisch.

untere Navigationsleiste
Abbildung 4: Eine Navigationsleiste am unteren Rand.

Um eine untere Navigationsleiste in deiner App zu erstellen, definiere die Leiste zuerst in deiner Hauptaktivität, wie unten gezeigt:

<LinearLayout>
    ...
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        ... />
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav"
        app:menu="@menu/menu_bottom_nav" />
</LinearLayout>

Rufen Sie als Nächstes in Ihrer Hauptaktivitätsklasse setupWithNavController() über die onCreate()-Methode Ihrer Hauptaktivität auf, wie unten gezeigt:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    setContentView(R.layout.activity_main)

    ...

    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    findViewById<BottomNavigationView>(R.id.bottom_nav)
        .setupWithNavController(navController)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.activity_main);

    ...

    NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    BottomNavigationView bottomNav = findViewById(R.id.bottom_nav);
    NavigationUI.setupWithNavController(bottomNav, navController);
}

Ab Navigation 2.4.0-alpha01 wird der Status jedes Menüpunkts gespeichert und wiederhergestellt, wenn Sie setupWithNavController verwenden.

Ein umfassendes Beispiel mit Navigation am unteren Rand finden Sie im Beispiel zur erweiterten Navigation von Android Architecture Components auf GitHub.

Auf Navigationsereignisse warten

Die Interaktion mit dem NavController ist die primäre Methode zum Navigieren zwischen Zielen. Der NavController ist dafür verantwortlich, den Inhalt von NavHost durch das neue Ziel zu ersetzen. In vielen Fällen befinden sich UI-Elemente wie eine obere App-Leiste oder andere persistente Navigationssteuerelemente wie BottomNavigationBar außerhalb des NavHost und müssen aktualisiert werden, wenn Sie zwischen Zielen wechseln.

NavController bietet eine OnDestinationChangedListener-Schnittstelle, die aufgerufen wird, wenn sich das aktuelle Ziel des NavController oder seine Argumente ändern. Über die Methode addOnDestinationChangedListener() kann ein neuer Listener registriert werden. Wenn addOnDestinationChangedListener() aufgerufen wird und das aktuelle Ziel vorhanden ist, wird es sofort an Ihren Listener gesendet.

NavigationUI verwendet OnDestinationChangedListener, um diese gängigen UI-Komponenten navigierbar zu machen. Beachten Sie jedoch, dass Sie auch allein OnDestinationChangedListener verwenden können, um Navigationsereignisse in jeder benutzerdefinierten UI oder Geschäftslogik zu erkennen.

Vielleicht haben Sie beispielsweise gängige UI-Elemente, die in einigen Bereichen Ihrer App angezeigt und in anderen ausgeblendet werden sollen. Mit Ihrem eigenen OnDestinationChangedListener können Sie diese UI-Elemente je nach Ziel selektiv ein- oder ausblenden, wie im folgenden Beispiel gezeigt:

Kotlin

navController.addOnDestinationChangedListener { _, destination, _ ->
   if(destination.id == R.id.full_screen_destination) {
       toolbar.visibility = View.GONE
       bottomNavigationView.visibility = View.GONE
   } else {
       toolbar.visibility = View.VISIBLE
       bottomNavigationView.visibility = View.VISIBLE
   }
}

Java

navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
   @Override
   public void onDestinationChanged(@NonNull NavController controller,
           @NonNull NavDestination destination, @Nullable Bundle arguments) {
       if(destination.getId() == R.id.full_screen_destination) {
           toolbar.setVisibility(View.GONE);
           bottomNavigationView.setVisibility(View.GONE);
       } else {
           toolbar.setVisibility(View.VISIBLE);
           bottomNavigationView.setVisibility(View.VISIBLE);
       }
   }
});

Argumentbasierte Listener

Alternativ können Sie im Navigationsdiagramm auch Argumente mit Standardwerten verwenden, die vom entsprechenden UI-Controller zur Aktualisierung seines Status verwendet werden können. Anstatt die Logik im OnDestinationChangedListener wie im vorherigen Beispiel auf die Ziel-ID zu stützen, können wir ein Argument im NavGraph erstellen:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/navigation\_graph"
    app:startDestination="@id/fragmentOne">
    <fragment
        android:id="@+id/fragmentOne"
        android:name="com.example.android.navigation.FragmentOne"
        android:label="FragmentOne">
        <action
            android:id="@+id/action\_fragmentOne\_to\_fragmentTwo"
            app:destination="@id/fragmentTwo" />
    </fragment>
    <fragment
        android:id="@+id/fragmentTwo"
        android:name="com.example.android.navigation.FragmentTwo"
        android:label="FragmentTwo">
        <argument
            android:name="ShowAppBar"
            android:defaultValue="true" />
    </fragment>
</navigation>

Dieses Argument wird nicht verwendet, wenn Sie zum Ziel navigieren, sondern um zusätzliche Informationen mithilfe von defaultValue an das Ziel anzuhängen. In diesem Fall gibt der Wert an, ob die App-Leiste an diesem Ziel angezeigt werden soll.

Wir können jetzt ein OnDestinationChangedListener in Activity hinzufügen:

Kotlin

navController.addOnDestinationChangedListener { _, _, arguments ->
    appBar.isVisible = arguments?.getBoolean("ShowAppBar", false) == true
}

Java

navController.addOnDestinationChangedListener(
        new NavController.OnDestinationChangedListener() {
            @Override
            public void onDestinationChanged(
                    @NonNull NavController controller,
                    @NonNull NavDestination destination,
                    @Nullable Bundle arguments
            ) {
                boolean showAppBar = false;
                if (arguments != null) {
                    showAppBar = arguments.getBoolean("ShowAppBar", false);
                }
                if(showAppBar) {
                    appBar.setVisibility(View.VISIBLE);
                } else {
                    appBar.setVisibility(View.GONE);
                }
            }
        }
);

Der NavController ruft diesen Callback immer dann auf, wenn sich das Navigationsziel ändert. Der Activity kann jetzt den Status oder die Sichtbarkeit seiner UI-Komponenten anhand der im Callback empfangenen Argumente aktualisieren.

Ein Vorteil dieses Ansatzes besteht darin, dass der Activity nur die Argumente in der Navigationsgrafik sieht und keine einzelnen Fragment-Rollen und -Zuständigkeiten kennt. Ebenso wissen die einzelnen Fragmente nichts über das enthaltende Activity und die zugehörigen UI-Komponenten.

Weitere Informationen

Weitere Informationen zur Navigation finden Sie in den folgenden Ressourcen.

Produktproben

Codelabs

Blogposts

Videos