Destinazioni attività

Nel grafico di navigazione, una destinazione può essere un'attività. Sebbene sia la scelta migliore di avere una singola attività nella tua app, spesso le app usano le attività per i diversi componenti o la schermata di un'app. Attività le destinazioni possono essere utili in questi casi.

Compose e Kotlin DSL

L'aggiunta di una destinazione di attività al grafico di navigazione è sostanzialmente la stessa sia in Compose sia quando si utilizza il Kotlin DSL con frammenti. Questo perché quando passi NavGraph al componibile NavHost, utilizzi lo stesso createGraph() lambda.

Per ulteriori informazioni, consulta la sezione Creare un grafico in modo programmatico utilizzando il DSL.

XML

La creazione di una destinazione attività è simile alla creazione di un frammento destinazione. Tuttavia, la natura di una destinazione per un'attività è abbastanza diverso.

Per impostazione predefinita, la Libreria di navigazione associa la NavController a un Activity e il grafico di navigazione attivo ha come ambito Activity, Se un utente passa a un altro Activity, lo stato attuale il grafico di navigazione non rientra più nell'ambito. Ciò significa che Activity destinazione deve essere considerata un endpoint all'interno di un grafico di navigazione.

Per aggiungere una destinazione per l'attività, specifica la destinazione Activity con i relativi nome completo della classe:

<?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>

Questo XML equivale alla seguente chiamata a startActivity():

Kotlin

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

Java

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

Potrebbero verificarsi casi in cui questo approccio non è appropriato. Ad esempio, potrebbe non avere una dipendenza in fase di compilazione dalla classe di attività oppure potresti preferiscono il livello indiretto di analizzare un intento implicito. La intent-filter nella voce manifest per la destinazione Activity indica come strutturare la destinazione Activity.

Considera ad esempio il seguente file manifest:

<?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 destinazione Activity corrispondente deve essere configurata con Attributi action e data corrispondenti a quelli nella voce manifest:

<?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>

Specificando targetPackage per l'attuale applicationId limita le all'applicazione corrente, che include l'app principale.

Lo stesso meccanismo può essere usato nei casi in cui vuoi che un'app destinazione. L'esempio seguente definisce una destinazione come un'app con un applicationId di 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>

Argomenti dinamici

Gli esempi precedenti utilizzavano URL fissi per raggiungere le destinazioni. Potresti devono supportare anche gli URL dinamici, in cui vengono inviate informazioni aggiuntive nell'ambito URL. Ad esempio, potresti inviare uno User-ID in un URL con un formato simile a https://example.com?userId=<actual user ID>.

In questo caso, utilizza dataPattern anziché l'attributo data. È quindi possibile fornire gli argomenti da sostituire con i segnaposto denominati all'interno il valore 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>

In questo esempio, puoi specificare un valore userId utilizzando Safe Args o con 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);

Questo esempio sostituisce someUser con {userId} e crea un valore URI di https://example.com?userId=someUser.