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 Fragments and the Kotlin DSL.

XML

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

Per impostazione predefinita, la Raccolta di navigazione collega il NavController a un layout Activity e il grafico di navigazione attivo è limitato al Activity attivo. Se un utente passa a un altro Activity, lo stato attuale il grafico di navigazione non rientra più nell'ambito. Ciò significa che una destinazione Activity deve essere considerata un endpoint all'interno di un grafo 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 è equivalente 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 anche dover supportare gli URL dinamici in cui vengono inviate informazioni aggiuntive nell'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.