Progetta il tuo grafico di navigazione

Il componente Navigazione utilizza un grafico di navigazione per gestire il traffico dell'app per la navigazione. Il grafico di navigazione è una struttura di dati che contiene destinazione all'interno dell'app e le connessioni tra di esse.

Tipi di destinazione

Esistono tre tipi generali di destinazioni: ospitate, di dialogo e attività. La nella tabella che segue vengono descritti questi tre tipi di destinazione e le relative finalità.

Tipo

Descrizione

Casi d'uso

Ospitato

Compila l'intero host di navigazione. In altre parole, le dimensioni di una destinazione ospitata corrispondono a quelle dell'host di navigazione e le destinazioni precedenti non sono visibili.

Schermate principali e dei dettagli.

Finestra di dialogo

Presenta i componenti dell'interfaccia utente overlay. Questa UI non è legata alla posizione dell'host di navigazione o alle sue dimensioni. Le destinazioni precedenti sono visibili sotto la destinazione.

Avvisi, selezioni, moduli.

Attività

Rappresenta schermate o funzionalità uniche all'interno dell'app.

Fungere da punto di uscita per il grafico di navigazione che avvia una nuova attività Android gestita separatamente dal componente Navigazione.

Nello sviluppo di Android moderno, un'app è costituita da una singola attività. Le destinazioni delle attività sono quindi ideali per interagire con attività di terze parti o nell'ambito del processo di migrazione.

Questo documento contiene esempi di destinazioni ospitate, che sono le più destinazioni comuni e fondamentali. Consulta le seguenti guide per informazioni su le altre destinazioni:

Framework

Sebbene lo stesso flusso di lavoro generale si applichi in tutti i casi, il modo in cui crei l'host della navigazione e il grafico dipendono dal framework dell'interfaccia utente utilizzato.

  • Scrivi: utilizza il componibile NavHost. Aggiungi un NavGraph utilizzando il Kotlin DSL. Puoi creare il grafico in due modi:
    • Come parte di NavHost: crea il grafico di navigazione direttamente come nell'aggiunta di NavHost.
    • In modo programmatico: utilizza il metodo NavController.createGraph(). per creare un NavGraph e passarlo direttamente al NavHost.
  • Frammenti: quando utilizzi frammenti con il framework di UI delle viste, utilizza un elemento NavHostFragment come organizzatore. Esistono diversi modi per creare una navigazione grafico:
    • In modo programmatico: usa la DSL Kotlin per creare un NavGraph e applicarla direttamente in NavHostFragment.
      • La funzione createGraph() utilizzata con Kotlin DSL per entrambi e Compose è lo stesso.
    • XML: scrivi l'host di navigazione e il grafico direttamente in XML.
    • Editor di Android Studio: utilizza l'editor GUI in Android Studio per per creare e modificare il grafico come file di risorse XML.
di Gemini Advanced.

Compose

In Compose, utilizza un oggetto o una classe serializzabile per definire una route. Un percorso descrive come raggiungere una destinazione e contiene tutte le informazioni richiesta dalla destinazione. Dopo aver definito i percorsi, utilizza NavHost componibili per creare il grafico di navigazione. Considera il seguente esempio:

@Serializable
object Profile
@Serializable
object FriendsList

val navController = rememberNavController()

NavHost(navController = navController, startDestination = Profile) {
    composable<Profile> { ProfileScreen( /* ... */ ) }
    composable<FriendsList> { FriendsListScreen( /* ... */ ) }
    // Add more destinations similarly.
}
  1. Un oggetto serializzabile rappresenta ciascuna delle due route, Profile e FriendsList.
  2. La chiamata al componibile NavHost trasmette un NavController e un percorso come destinazione di partenza.
  3. La funzione lambda passata a NavHost alla fine chiama NavController.createGraph() e restituisce un NavGraph.
  4. Ogni route viene fornita come argomento di tipo NavGraphBuilder.composable<T>() che aggiunge la destinazione al risultanti NavGraph.
  5. Il valore lambda passato a composable è ciò che mostra NavHost destinazione.
di Gemini Advanced.

Informazioni su lambda

Per comprendere meglio la funzione lambda che crea NavGraph, considera che questo lo stesso grafico dello snippet precedente, puoi creare NavGraph separatamente utilizzando NavController.createGraph() e passalo a NavHost direttamente:

val navGraph by remember(navController) {
  navController.createGraph(startDestination = Profile)) {
    composable<Profile> { ProfileScreen( /* ... */ ) }
    composable<FriendsList> { FriendsListScreen( /* ... */ ) }
  }
}
NavHost(navController, navGraph)

Supera argomenti

Se devi trasferire i dati a una destinazione, definisci la route con una classe contiene parametri. Ad esempio, la route Profile è una classe di dati con un name .

@Serializable
data class Profile(val name: String)

Ogni volta che devi passare argomenti a quella destinazione, crea un'istanza della classe di route, passando gli argomenti al costruttore della classe.

Per gli argomenti facoltativi, crea campi nulli con un valore predefinito.

@Serializable
data class Profile(val nickname: String? = null)

Ottieni istanza route

Puoi ottenere l'istanza di route con NavBackStackEntry.toRoute() o SavedStateHandle.toRoute(). Quando crei una destinazione utilizzando composable(), NavBackStackEntry è disponibile come parametro.

@Serializable
data class Profile(val name: String)

val navController = rememberNavController()

NavHost(navController = navController, startDestination = Profile(name="John Smith")) {
    composable<Profile> { backStackEntry ->
        val profile: Profile = backStackEntry.toRoute()
        ProfileScreen(name = profile.name) }
}

Tieni presente quanto segue in questo snippet:

  • Il percorso Profile specifica la destinazione di partenza nella navigazione con "John Smith" come argomento per name.
  • La destinazione stessa è il blocco composable<Profile>{}.
  • Il componibile ProfileScreen prende il valore di profile.name name argomento.
  • Di conseguenza, il valore "John Smith" passa a ProfileScreen.

Esempio minimo

Un esempio completo di NavController e NavHost che lavorano insieme:

@Serializable
data class Profile(val name: String)

@Serializable
object FriendsList

// Define the ProfileScreen composable.
@Composable
fun ProfileScreen(
    profile: Profile
    onNavigateToFriendsList: () -> Unit,
  ) {
  Text("Profile for ${profile.name}")
  Button(onClick = { onNavigateToFriendsList() }) {
    Text("Go to Friends List")
  }
}

// Define the FriendsListScreen composable.
@Composable
fun FriendsListScreen(onNavigateToProfile: () -> Unit) {
  Text("Friends List")
  Button(onClick = { onNavigateToProfile() }) {
    Text("Go to Profile")
  }
}

// Define the MyApp composable, including the `NavController` and `NavHost`.
@Composable
fun MyApp() {
  val navController = rememberNavController()
  NavHost(navController, startDestination = Profile(name = "John Smith")) {
    composable<Profile> { backStackEntry ->
        val profile: Profile = backStackEntry.toRoute()
        ProfileScreen(
            profile = profile,
            onNavigateToFriendsList = {
                navController.navigate(route = FriendsList)
            }
        )
    }
    composable<FriendsList> {
      FriendsListScreen(
        onNavigateToProfile = {
          navController.navigate(
            route = Profile(name = "Aisha Devi")
          )
        }
      )
    }
  }
}

Come dimostrato dallo snippet, invece di passare il valore NavController al tuo componibili, esponi un evento all'elemento NavHost. Vale a dire che gli elementi componibili presentano un parametro di tipo () -> Unit per cui NavHost passa un parametro lambda che chiama NavController.navigate().

Frammenti

Come spiegato nelle sezioni precedenti, quando utilizzi i frammenti hai la possibilità per creare un grafico di navigazione in modo programmatico utilizzando Kotlin DSL, XML o Editor di Android Studio.

Le seguenti sezioni descrivono nel dettaglio questi diversi approcci.

In modo programmatico

Kotlin DSL offre un modo programmatico per creare un grafico di navigazione con di grandi dimensioni. Questa procedura è per molti versi più ordinata e moderna rispetto all'uso di un file XML di risorse.

Considera l'esempio seguente, che implementa un grafico di navigazione a due schermate.

Innanzitutto è necessario creare l'elemento NavHostFragment, che non deve includere un elemento app:navGraph:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</FrameLayout>

Poi, passa id di NavHostFragment a NavController.findNavController Questa operazione associa il NavController a NavHostFragment.

Successivamente, la chiamata a NavController.createGraph() collega il grafico a NavController e, di conseguenza, anche ai NavHostFragment:

@Serializable
data class Profile(val name: String)

@Serializable
object FriendsList

// Retrieve the NavController.
val navController = findNavController(R.id.nav_host_fragment)

// Add the graph to the NavController with `createGraph()`.
navController.graph = navController.createGraph(
    startDestination = Profile(name = "John Smith")
) {
    // Associate each destination with one of the route constants.
    fragment<ProfileFragment, Profile> {
        label = "Profile"
    }

    fragment<FriendsListFragment, FriendsList>() {
        label = "Friends List"
    }

    // Add other fragment destinations similarly.
}

Utilizzare DSL in questo modo è molto simile al flusso di lavoro descritto precedente su Scrivi. Ad esempio, sia lì che qui, La funzione NavController.createGraph() genera il valore NavGraph. Allo stesso modo, anche se NavGraphBuilder.composable() aggiunge destinazioni componibili al grafico, qui NavGraphBuilder.fragment() aggiunge una destinazione per il frammento.

Per ulteriori informazioni su come utilizzare il DSL Kotlin, consulta la sezione Creare un grafico con la DSL NavGraphBuilder.

XML

Puoi scrivere direttamente l'XML. L'esempio seguente rispecchia ed è equivalente all'esempio in due schermate della sezione precedente.

Innanzitutto, crea un NavHostFragment. funge da host di navigazione che contiene il grafico di navigazione effettivo.

Un'implementazione minima di un NavHostFragment:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:navGraph="@navigation/nav_graph" />

</FrameLayout>

NavHostFragment contiene l'attributo app:navGraph. Utilizza questo attributo per collegare il tuo grafico di navigazione all'host di navigazione. Di seguito è riportato un di come implementare il grafico:

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_graph"
    app:startDestination="@id/profile">

    <fragment
        android:id="@+id/profile"
        android:name="com.example.ProfileFragment"
        android:label="Profile">

        <!-- Action to navigate from Profile to Friends List. -->
        <action
            android:id="@+id/action_profile_to_friendslist"
            app:destination="@id/friendslist" />
    </fragment>

    <fragment
        android:id="@+id/friendslist"
        android:name="com.example.FriendsListFragment"
        android:label="Friends List" />

    <!-- Add other fragment destinations similarly. -->
</navigation>

Le azioni consentono di definire le connessioni tra destinazioni diverse. Nella in questo esempio, il frammento profile contiene un'azione che porta a friendslist. Per ulteriori informazioni, vedi Utilizzare le azioni di navigazione e di grandi dimensioni.

Editor

Puoi gestire il grafico di navigazione dell'app utilizzando l'Editor di navigazione in: Android Studio. Si tratta essenzialmente di una GUI che puoi utilizzare per creare e modificare NavigationFragment XML, come illustrato nella sezione precedente.

Per ulteriori informazioni, vedi Editor di navigazione.

Grafici nidificati

Puoi anche utilizzare grafici nidificati. Ciò comporta l'uso di un grafico come strumento di navigazione destinazione. Per ulteriori informazioni, consulta la sezione Grafici nidificati.

Per approfondire

Per altri concetti fondamentali sulla navigazione, consulta le seguenti guide:

  • Panoramica: assicurati di leggere la panoramica generale del menu di navigazione. di strumento di authoring.
  • Destinazioni delle attività:esempi di come implementare le destinazioni. che portano l'utente alle attività.
  • Destinazioni di dialogo: esempi di come creare destinazioni che indirizzare l'utente a una finestra di dialogo.
  • Raggiungere una destinazione: una guida dettagliata che spiega come: passare da una destinazione a un'altra.
  • Grafici nidificati: una guida approfondita su come nidificare un sistema di navigazione grafico all'interno di un altro.