活動目的地

在導覽圖中,目的地可以是活動。雖然最佳做法是在應用程式中採用單一活動,但應用程式通常會針對應用程式中的不同元件或畫面,分別使用不同活動。在這種情況下,活動目的地非常實用。

Compose 和 Kotlin DSL

在導覽圖中新增活動目的地的做法大致相同 ,以及搭配使用 Kotlin DSL 與片段時。這是因為將 NavGraph 傳遞至 NavHost 可組合函式時,您可以使用相同的 createGraph() lambda。

詳情請參閱「片段和 Kotlin DSL」。

XML

建立活動目的地與建立片段目的地類似,但活動目的地的性質不大相同。

根據預設,Navigation 程式庫會將 NavController 附加至 Activity 版面配置,且使用中的導覽圖範圍僅限於使用中的 Activity。如果使用者前往不同 Activity,目前的導覽圖就變得不在範圍內。這表示 Activity 目的地應視為導覽圖內的端點。

如要新增活動目的地,請以目的地的完整類別名稱指定目的地 Activity

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

這個 XML 等同於以下對 startActivity() 的呼叫:

Kotlin

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

Java

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

在某些情況下,這個做法可能不適用,例如活動類別可能沒有編譯時間依附元件,或者您可能偏好使用隱含意圖的間接層級等情況。至於您需要如何建立 Activity 目的地的結構,則取決於目的地 Activity 資訊清單項目中的 intent-filter

以下列資訊清單檔案為例:

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

設定相對應的 Activity 目的地時,需要使用 actiondata 屬性,且必須符合資訊清單項目中的屬性:

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

targetPackage 指定為目前的 applicationId 後,會將範圍限定在包含主應用程式的目前應用程式。

如要將特定應用程式做為目的地,可以採用相同機制。以下範例將目的地定義為含有 com.example.android.another.appapplicationId 的應用程式。

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

動態引數

先前的範例是使用固定網址前往目的地。您可能也需要支援動態網址,在網址中傳送額外資訊。舉例來說,您或許能在格式類似於 https://example.com?userId=<actual user ID> 的網址中傳送使用者 ID。

在此情況下,請使用 dataPattern,而非 data 屬性。接著,您可以在 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>

在此範例中,您可以使用 Safe ArgsBundle 指定 userId 值:

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

此範例使用 someUser 取代 {userId},並建立 https://example.com?userId=someUser 的 URI 值。