Aktivitätsziele

In Ihrer Navigationsgrafik kann ein Ziel eine Aktivität sein. Es hat sich bewährt, eine einzelne Aktivität in einer App zu verwenden. Allerdings verwenden Apps oft separate Aktivitäten für unterschiedliche Komponenten oder Bildschirme innerhalb einer App. Aktivitätsziele können in solchen Fällen nützlich sein.

Compose und Kotlin-DSL

Das Hinzufügen eines Aktivitätsziels zu einem Navigationsdiagramm funktioniert in Compose und bei Verwendung von Kotlin-DSL mit Fragmenten im Wesentlichen gleich. Das liegt daran, dass Sie beim Übergeben von NavGraph an die zusammensetzbare Funktion NavHost dasselbe Lambda-Element createGraph() verwenden.

Weitere Informationen finden Sie unter Diagramme mit Kotlin-DSL programmatisch erstellen.

XML

Das Erstellen eines Ziels für Aktivitäten ähnelt dem Erstellen eines Fragmentziels. Aktivitätsziele sind jedoch ganz anders.

In der Navigationsbibliothek wird die NavController standardmäßig an ein Activity-Layout angehängt und die aktive Navigationsgrafik ist auf den aktiven Activity beschränkt. Wenn ein Nutzer eine andere Activity aufruft, fällt das aktuelle Navigationsdiagramm nicht mehr in den Bereich. Das bedeutet, dass ein Activity-Ziel in einem Navigationsdiagramm als Endpunkt betrachtet werden sollte.

Wenn Sie ein Aktivitätsziel hinzufügen möchten, geben Sie das Ziel Activity mit seinem voll qualifizierten Klassennamen an:

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

Diese XML-Datei entspricht dem folgenden Aufruf von startActivity():

Kotlin

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

Java

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

Es kann vorkommen, dass dieser Ansatz nicht geeignet ist. Es kann beispielsweise sein, dass keine Kompilierungszeit von der Aktivitätsklasse abhängig ist oder dass Sie den Grad der Indirektion bevorzugen, wenn Sie einen impliziten Intent durchlaufen. Der intent-filter im Manifesteintrag für die Ziel-Activity gibt vor, wie das Activity-Ziel strukturiert werden muss.

Betrachten Sie zum Beispiel die folgende Manifestdatei:

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

Das entsprechende Activity-Ziel muss mit den Attributen action und data konfiguriert werden, die mit denen im Manifesteintrag übereinstimmen:

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

Wenn Sie targetPackage auf den aktuellen applicationId festlegen, wird der Bereich auf die aktuelle Anwendung beschränkt, zu der auch die Hauptanwendung gehört.

Derselbe Mechanismus kann auch für Fälle verwendet werden, in denen eine bestimmte Anwendung als Ziel verwendet werden soll. Im folgenden Beispiel wird ein Ziel als eine Anwendung mit einem applicationId von com.example.android.another.app definiert.

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

Dynamische Argumente

In den vorherigen Beispielen wurden feste URLs verwendet, um zu Zielen zu gelangen. Möglicherweise müssen auch dynamische URLs unterstützt werden, bei denen zusätzliche Informationen als Teil der URL gesendet werden. Sie können beispielsweise eine Nutzer-ID in einer URL mit einem Format wie https://example.com?userId=<actual user ID> senden.

Verwenden Sie in diesem Fall anstelle des Attributs data dataPattern. Sie können dann Argumente angeben, die im Wert von dataPattern durch benannte Platzhalter ersetzt werden:

<?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 diesem Beispiel können Sie einen userId-Wert entweder mit Safe Args oder mit Bundle angeben:

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);

In diesem Beispiel wird {userId} durch someUser ersetzt und der URI-Wert https://example.com?userId=someUser wird erstellt.