在導覽圖中,目的地可以是活動。雖然最佳做法是在應用程式中採用單一活動,但應用程式通常會針對應用程式中的不同元件或畫面分別使用不同的活動。在這類情況下,活動目的地非常實用。
Compose 和 Kotlin DSL
在 Compose 中以及將 Kotlin DSL 與片段搭配使用時,在導覽圖中加入活動目的地基本上都是相同的。這是因為將 NavGraph
傳遞至 NavHost
可組合項時,您可以使用相同的 createGraph()
lambda。
詳情請參閱「使用 Kotlin DSL 透過程式輔助方式建構圖表」。
XML
建立活動目的地與建立片段目的地類似。但是,活動目的地的性質有很大的不同。
根據預設,導覽程式庫會將 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
資訊清單項目中的 intent-filter
決定了 Activity
目的地的結構。
以下列資訊清單檔案為例:
<?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
目的地必須使用與資訊清單項目中相符的 action
和 data
屬性設定:
<?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.app
的 applicationId
的應用程式。
<?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 Args 或 Bundle
指定 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 值。