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