活動目的地

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

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 值。