Le composant de navigation utilise un graphique de navigation pour gérer la navigation dans votre appli. Le graphique de navigation est une structure de données qui contient chaque destination de votre appli ainsi que les connexions qui s'établissent entre elles.
Types de destinations
Il existe trois principaux types de destinations : destination hébergée, destination de boîte de dialogue et destination d'activité. Le tableau ci-dessous décrit ces trois types de destinations ainsi que leurs objectifs.
Type |
Description |
Cas d'utilisation |
---|---|---|
Destination hébergée |
Occupe l'intégralité de l'hôte de navigation. Autrement dit, la taille d'une destination hébergée est identique à celle de l'hôte de navigation, et les destinations précédentes ne sont pas visibles. |
Écran principal et page d'informations |
Destination de boîte de dialogue |
Présente les composants d'interface utilisateur superposés. Cette interface utilisateur n'est pas liée à l'emplacement de l'hôte de navigation ni à sa taille. Les destinations précédentes sont visibles sous la destination. |
Alertes, sélections, formulaires. |
Destination d'activité |
Représente des pages ou des fonctionnalités uniques au sein de l'appli. |
Sert de point de sortie au graphique de navigation qui lance une nouvelle activité Android gérée indépendamment du composant Navigation. Dans Modern Android Development, une appli se compose d'une seule activité. Lorsqu'elles interagissent avec des activités tierces ou dans le cadre du processus de migration, les destinations des activités sont ainsi mieux utilisées. |
Ce document contient des exemples de destinations hébergées, qui sont les destinations les plus courantes et les plus fondamentales. Pour en savoir plus sur les autres destinations, consultez les guides suivants :
Frameworks
Bien que le même workflow général s'applique dans tous les cas, la manière exacte de créer un hôte et un graphique de navigation dépend du framework d'interface utilisateur que vous utilisez.
- Compose : utilisez le composable
NavHost
. Ajoutez-y unNavGraph
à l'aide du DSL Kotlin. Il existe deux manières de créer le graphique :- Dans NavHost : construisez le graphique de navigation directement lors de l'ajout de
NavHost
. - Par programmation : utilisez la méthode
NavController.createGraph()
pour créer unNavGraph
et le transmettre directement àNavHost
.
- Dans NavHost : construisez le graphique de navigation directement lors de l'ajout de
- Fragments:lorsque vous utilisez des fragments avec le framework d'UI Vues, utilisez un
NavHostFragment
comme hôte. Il existe plusieurs façons de créer un graphique de navigation :- De façon programmatique:utilisez le DSL Kotlin pour créer un
NavGraph
et l'appliquer directement àNavHostFragment
.- La fonction
createGraph()
utilisée avec le DSL Kotlin pour les deux fragments ainsi que Compose est la même.
- La fonction
- XML : écrivez votre hôte de navigation ainsi que votre graphique de navigation directement en XML.
- Éditeur Android Studio : utilisez l'éditeur IUG dans Android Studio pour créer et ajuster votre graphique en tant que fichier de ressources XML.
- De façon programmatique:utilisez le DSL Kotlin pour créer un
Compose
Dans Compose, utilisez un objet ou une classe sérialisable pour définir un parcours. Un itinéraire décrit comment accéder à une destination et contient toutes les informations requises pour y parvenir.
Utilisez l'annotation @Serializable
pour créer automatiquement les méthodes de sérialisation et de désérialisation nécessaires pour vos types de parcours. Cette annotation est fournie par le plug-in de sérialisation Kotlin. Suivez ces instructions pour ajouter ce plug-in.
Une fois que vous avez défini vos itinéraires, utilisez le composable NavHost
pour créer votre graphique de navigation. Prenons l'exemple suivant :
@Serializable
object Profile
@Serializable
object FriendsList
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Profile) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
// Add more destinations similarly.
}
- Un objet sérialisable représente chacun des deux itinéraires,
Profile
etFriendsList
. - L'appel du composable
NavHost
transmet unNavController
et un itinéraire pour la destination de départ. - Le lambda transmis à
NavHost
appelle finalementNavController.createGraph()
et renvoie unNavGraph
. - Chaque itinéraire est fourni en tant qu'argument de type à
NavGraphBuilder.composable<T>()
, qui ajoute la destination à l'NavGraph
généré. - Le lambda transmis à
composable
est ce queNavHost
affiche pour cette destination.
Comprendre le lambda
Pour mieux comprendre le lambda qui crée le NavGraph
, n'oubliez pas que pour créer le même graphique que dans l'extrait précédent, vous pouvez créer le NavGraph
séparément à l'aide de NavController.createGraph()
et le transmettre directement à NavHost
:
val navGraph by remember(navController) {
navController.createGraph(startDestination = Profile)) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
}
}
NavHost(navController, navGraph)
Transmettre des arguments
Si vous devez transmettre des données à une destination, définissez l'itinéraire avec une classe qui comporte des paramètres. Par exemple, le chemin Profile
est une classe de données avec un paramètre name
.
@Serializable
data class Profile(val name: String)
Chaque fois que vous devez transmettre des arguments à cette destination, vous créez une instance de votre classe d'itinéraire, en transmettant les arguments au constructeur de la classe.
Pour les arguments facultatifs, créez des champs nullables avec une valeur par défaut.
@Serializable
data class Profile(val nickname: String? = null)
Obtenir une instance d'itinéraire
Vous pouvez obtenir l'instance de route avec NavBackStackEntry.toRoute()
ou SavedStateHandle.toRoute()
. Lorsque vous créez une destination à l'aide de composable()
, NavBackStackEntry
est disponible en tant que paramètre.
@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) }
}
Notez les points suivants dans cet extrait de code:
- L'itinéraire
Profile
spécifie la destination de départ dans le graphique de navigation, avec"John Smith"
comme argument pourname
. - La destination elle-même est le bloc
composable<Profile>{}
. - Le composable
ProfileScreen
prend la valeur deprofile.name
pour son propre argumentname
. - Par conséquent, la valeur
"John Smith"
est transmise àProfileScreen
.
Exemple minimal
Voici un exemple complet de cas où NavController
et NavHost
fonctionnent ensemble:
@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")
)
}
)
}
}
}
Comme le montre l'extrait, plutôt que de transmettre le NavController
à vos composables, exposez un événement à NavHost
. Autrement dit, vos composables doivent comporter un paramètre de type () -> Unit
pour lequel NavHost
transmet un lambda qui appelle NavController.navigate()
.
Fragments
Comme indiqué dans les sections précédentes, lorsque vous utilisez des fragments, vous avez la possibilité de créer un graphique de navigation par programmation à l'aide du DSL Kotlin, du XML ou de l'éditeur Android Studio.
Les sections suivantes reviennent plus en détail sur ces différentes approches.
Par programmation
Le DSL Kotlin permet de créer un graphique de navigation avec des fragments de façon programmatique. À bien des égards, cette méthode est plus pratique et plus moderne que le recours à un fichier de ressources XML.
Prenons l'exemple suivant, qui implémente un graphique de navigation sur deux écrans.
Il est avant tout nécessaire de créer le NavHostFragment
, qui ne doit pas inclure d'élément 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>
Transmettez ensuite l'id
du NavHostFragment
à NavController.findNavController
. Cela a pour effet d'associer NavController au NavHostFragment
.
Ensuite, l'appel envoyé à NavController.createGraph()
associe le graphique au NavController
et, par conséquent, au 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.
}
Cette manière d'utiliser le DSL est très semblable au workflow décrit dans la section précédente sur Compose. Par exemple, ici et là, la fonction NavController.createGraph()
génère le NavGraph
. De même, tandis que NavGraphBuilder.composable()
ajoute des destinations de composable au graphique, NavGraphBuilder.fragment()
ajoute une destination de fragment.
Pour en savoir plus sur l'utilisation du DSL Kotlin, consultez la section Créer un graphe par programmation à l'aide du langage DSL Kotlin.
XML
Vous pouvez rédiger vous-même le code XML directement. L'exemple suivant est le même que celui présenté à la section précédente (sur deux écrans).
Commencez par créer un NavHostFragment
. Ce dernier servira d'hôte de navigation et contiendra le graphique de navigation.
Implémentation minimale d'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>
Le NavHostFragment
contient l'attribut app:navGraph
. Utilisez cet attribut pour connecter votre graphique de navigation à l'hôte de navigation. Voici un exemple d'implémentation du graphique :
<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>
Les actions vous permettent de définir les connexions entre les différentes destinations. Dans cet exemple, le fragment profile
contient une action qui permet d'accéder à friendslist
. Pour en savoir plus, consultez la section Utiliser les actions de navigation et les fragments.
Éditeur
Vous pouvez gérer le graphique de navigation de votre appli à l'aide de l'éditeur de navigation d'Android Studio. Il s'agit essentiellement d'une IUG que vous pouvez utiliser pour créer et modifier votre fichier XML NavigationFragment
, comme indiqué dans la section précédente.
Pour en savoir plus, consultez la section Éditeur de navigation.
Graphiques imbriqués
Vous pouvez également utiliser des graphiques imbriqués. Cela implique l'utilisation d'un graphique comme destination de navigation. Pour en savoir plus, consultez la section Graphiques imbriqués.
Complément d'informations
Pour plus de concepts de base concernant la navigation, consultez les guides suivants :
- Présentation : veillez à lire la présentation générale du composant Navigation.
- Destinations d'activité : exemples d'implémentation de destinations qui redirigent l'utilisateur vers des activités.
- Destinations de boîte de dialogue : exemples illustrant la façon de créer des destinations qui redirigent l'utilisateur vers une boîte de dialogue.
- Accéder à une destination : guide détaillé expliquant comment passer d'une destination à une autre.
- Graphiques imbriqués:guide détaillé sur l'imbrication d'un graphique de navigation dans un autre.