Créer des destinations

Vous pouvez créer une destination à partir d'un fragment ou d'une activité existants. Vous pouvez également utiliser l'éditeur de navigation pour créer une destination ou un espace réservé à remplacer ultérieurement par un fragment ou une activité.

Créer une destination à partir d'un fragment ou d'une activité existants

Dans l'éditeur de navigation, si vous souhaitez ajouter un type de destination existant à votre graphique de navigation, cliquez sur Nouvelle destination, puis sur la destination correspondante dans le menu déroulant qui s'affiche. Vous pouvez alors prévisualiser la destination dans la vue Conception, ainsi que le code XML correspondant dans la vue Texte de votre graphique de navigation.

Créer une destination de fragment

Pour ajouter un nouveau type de destination à l'aide de l'éditeur de navigation, procédez comme suit :

  1. Dans l'éditeur de navigation, cliquez sur l'icône Nouvelle destination , puis sur Créer une destination.
  2. Dans la boîte de dialogue Nouveau composant Android qui s'affiche, créez votre fragment. Pour en savoir plus sur les fragments, consultez les documents concernant les fragments.

De retour dans l'éditeur de navigation, notez qu'Android Studio a ajouté cette destination au graphique.

L'image 1 est un exemple de destination et d'espace réservé pour une destination.

Image 1. Une destination et un espace réservé pour une destination

Créer une destination à partir d'un DialogFragment

Si vous disposez déjà d'un DialogFragment, vous pouvez utiliser l'élément <dialog> pour ajouter la boîte de dialogue à votre graphique de navigation, comme illustré dans l'exemple suivant :

<?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/nav_graph">

...

<dialog
    android:id="@+id/my_dialog_fragment"
    android:name="androidx.navigation.myapp.MyDialogFragment">
    <argument android:name="myarg" android:defaultValue="@null" />
        <action
            android:id="@+id/myaction"
            app:destination="@+id/another_destination"/>
</dialog>

...

</navigation>

Créer une destination d'activité

La création d'une destination Activity est semblable à la création d'une destination Fragment. Cependant, la nature d'une destination Activity est assez différente.

Par défaut, la bibliothèque Navigation associe NavController à une mise en page Activity, et le graphique de navigation active est limité au Activity actif. Si un utilisateur accède à un autre Activity, le graphique de navigation actuel n'est plus inclus dans le champ d'application. Cela signifie qu'une destination Activity doit être considérée comme un point de terminaison dans un graphique de navigation.

Pour ajouter une destination Activity, précisez la destination Activity avec son nom de classe complet :

<?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/simpleFragment">

    <activity
        android:id="@+id/sampleActivityDestination"
        android:name="com.example.android.navigation.activity.DestinationActivity"
        android:label="@string/sampleActivityTitle" />
</navigation>

Ce fichier XML équivaut à l'appel suivant de startActivity() :

Kotlin

startActivity(Intent(context, DestinationActivity::class.java))

Java

startActivity(new Intent(context, DestinationActivity.class));

Dans certains cas, cette approche n'est pas adaptée. Par exemple, vous ne disposez peut-être pas d'une dépendance en temps de compilation sur la classe d'activité ou vous préférez le niveau d'indirection d'un intent implicite. Le intent-filter dans l'entrée du fichier manifeste de destination Activity indique la façon dont vous devez structurer la destination Activity.

Prenons l'exemple du fichier manifeste suivant :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.navigation.activity">
    <application>
        <activity android:name=".DestinationActivity">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <data
                    android:host="example.com"
                    android:scheme="https" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

La destination Activity correspondante doit être configurée avec les attributs action et data correspondant à ceux de l'entrée du fichier manifeste :

<?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/simpleFragment">
    <activity
        android:id="@+id/localDestinationActivity"
        android:label="@string/localActivityTitle"
        app:action="android.intent.action.VIEW"
        app:data="https://example.com"
        app:targetPackage="${applicationId}" />
</navigation>

Si vous définissez targetPackage avec la valeur applicationId actuelle, vous limitez la portée à l'application actuelle, qui inclut l'application principale.

Le même mécanisme peut être utilisé si vous souhaitez qu'une application spécifique devienne la destination. L'exemple suivant définit une destination comme une application avec un applicationId défini sur com.example.android.another.app.

<?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/simpleFragment">
    <activity
        android:id="@+id/localDestinationActivity"
        android:label="@string/localActivityTitle"
        app:action="android.intent.action.VIEW"
        app:data="https://example.com"
        app:targetPackage="com.example.android.another.app" />
</navigation>

Arguments dynamiques

Les exemples précédents utilisaient des URL fixes pour accéder aux destinations. Vous devrez peut-être également accepter les URL dynamiques, qui incluent des informations supplémentaires. Par exemple, vous pouvez envoyer un ID utilisateur dans une URL dans un format semblable à https://example.com?userId=<actual user ID>.

Dans ce cas, utilisez dataPattern à la place de l'attribut data. Vous pouvez ensuite fournir des arguments à remplacer pour les espaces réservés nommés dans la valeur dataPattern :

<?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/simpleFragment">
    <activity
        android:id="@+id/localDestinationActivity"
        android:label="@string/localActivityTitle"
        app:action="android.intent.action.VIEW"
        app:dataPattern="https://example.com?userId={userId}"
        app:targetPackage="com.example.android.another.app">
        <argument
            android:name="userId"
            app:argType="string" />
    </activity>
</navigation>

Dans cet exemple, vous pouvez définir une valeur userId à l'aide de Safe Args ou d'un Bundle :

Kotlin

navController.navigate(
    R.id.localDestinationActivity,
    bundleOf("userId" to "someUser")
)

Java

Bundle args = new Bundle();
args.putString("userId", "someUser");
navController.navigate(R.id.localDestinationActivity, args);

Cet exemple remplace someUser par {userId} et crée la valeur d'URI https://example.com?userId=someUser.

Espaces réservés pour des destinations

Vous pouvez utiliser des espaces réservés pour représenter des destinations non implémentées. Un espace réservé sert de représentation visuelle d'une destination. Dans l'éditeur de navigation, vous pouvez utiliser des espaces réservés comme n'importe quelle autre destination.