導覽元件能以簡單又通用的方式導覽至目的地。這個介面適用於多種情況和 UI 架構。舉例來說,您可以將 Navigation 元件與 Compose、檢視區塊、片段、活動,甚至是自訂 UI 架構搭配使用。
本指南說明如何使用 Navigation 元件,在不同的情境下前往目的地。
使用 NavController
您在目的地之間移動的金鑰類型為 NavController
。如要進一步瞭解類別本身以及如何建立執行個體,請參閱「建立導覽控制器」。本指南詳細說明使用方式。
導覽
無論您使用何種 UI 架構,都可以透過 NavController.navigate()
這個單一函式前往目的地。
navigate()
有許多超載可用。您應根據自身確切情況選擇相應的超載。舉例來說,前往可組合函式和檢視畫面時,應分別使用不同的超載。
以下各節概略說明您可使用的幾個主要 navigate()
超載。
導覽至可組合函式
如要前往可組合函式,應使用 NavController.navigate<T>
。透過這個超載,navigate()
會使用您傳遞類型的 route
引數。這可做為目的地的索引鍵。
@Serializable
object FriendsList
navController.navigate(route = FriendsList)
如要前往導覽圖表中的可組合項,請先定義 NavGraph
,讓每個目的地對應一種類型。如果是可組合項,您可以使用 composable()
函式完成此操作。
從可組合函式公開事件
當可組合函式需要前往新的畫面時,您不應向其傳遞 NavController
參照,這樣才能直接呼叫 navigate()
。根據單向資料流 (UDF) 原則,可組合項應改為公開 NavController
處理的事件。
更直接地說,可組合函式應含有 () -> Unit
類型的參數。如果您使用 composable()
函式在 NavHost
中新增目的地,請將對 NavController.navigate()
的呼叫傳遞至可組合函式。
如需範例,請參閱以下子節。
範例
依上述程式碼片段進行示範,在以下程式碼片段中觀察這幾點:
- 圖表中的每個目的地都是使用路徑建立,路徑是可序列化的物件或類別,用於描述該目的地所需的資料。
MyAppNavHost
可組合函式會保留NavController
例項。- 因此,對
navigate()
的呼叫應該會在其中發生,而不是在ProfileScreen
這類階層較低的可組合函式中。 ProfileScreen
包含一個按鈕,可在使用者點選時將使用者導向FriendsList
。不過,此按鈕本身不會呼叫navigate()
。- 取而代之的是,按鈕會呼叫要公開為
onNavigateToFriends
參數的函式。 - 當
MyAppNavHost
將ProfileScreen
新增至導覽圖時,其會為onNavigateToFriends
傳遞呼叫navigate(route = FriendsList
的 lambda。 - 這可確保使用者在按下按鈕
ProfileScreen
後正確前往FriendsListScreen
。
@Serializable
object Profile
@Serializable
object FriendsList
@Composable
fun MyAppNavHost(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
) {
NavHost(
modifier = modifier,
navController = navController,
startDestination = Profile
) {
composable<Profile> {
ProfileScreen(
onNavigateToFriends = { navController.navigate(route = FriendsList) },
/*...*/
)
}
composable<FriendsList> { FriendsListScreen(/*...*/) }
}
}
@Composable
fun ProfileScreen(
onNavigateToFriends: () -> Unit,
/*...*/
) {
/*...*/
Button(onClick = onNavigateToFriends) {
Text(text = "See friends list")
}
}
使用整數 ID 進行導覽
如要使用整數 ID 前往目的地,請呼叫 navigate(int)
超載,這會使用一項操作或一個目的地的資源 ID。下列程式碼片段顯示如何使用這個超載前往 ViewTransactionsFragment
:
Kotlin
viewTransactionsButton.setOnClickListener { view ->
view.findNavController().navigate(R.id.viewTransactionsAction)
}
Java
viewTransactionsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Navigation.findNavController(view).navigate(R.id.viewTransactionsAction);
}
});
使用 ID 進行導覽時,應盡可能使用操作。操作可在瀏覽圖中提供其他資訊,以視覺化的方式呈現出目的地之間如何相互連結。
使用 NavDeepLinkRequest 進行導覽
如要前往隱含深層連結目的地,請使用 navigate(NavDeepLinkRequest)
超載。下列程式碼片段說明這個方法的實作方式:
Kotlin
val request = NavDeepLinkRequest.Builder
.fromUri("android-app://androidx.navigation.app/profile".toUri())
.build()
findNavController().navigate(request)
Java
NavDeepLinkRequest request = NavDeepLinkRequest.Builder
.fromUri(Uri.parse("android-app://androidx.navigation.app/profile"))
.build()
NavHostFragment.findNavController(this).navigate(request)
與使用操作或目的地 ID 進行導覽不同的是,無論目的地是否可見,您都可以透過圖表前往任何深層連結。您可以前往目前圖表上的目的地,也可以前往完全不同圖表上的目的地。
操作和 MIME 類型
除了 Uri
以外,NavDeepLinkRequest
也支援含有操作及 MIME 類型的深層連結。如要在要求中新增操作,請使用 fromAction()
或 setAction()
;如要在要求中加入 MIME 類型,請使用 fromMimeType()
或 setMimeType()
。
為了讓 NavDeepLinkRequest
正確比對隱含深層連結目的地,URI、操作及 MIME 類型都必須與目的地中的 NavDeepLink
相符。URI 必須與模式相符、操作須完全相符,而 MIME 類型必須具有關聯性。例如 image/jpg
就與 image/\*
相符。
其他情況
本文件說明 NavController.navigate()
最常見的用途和使用方式。但是,該函式有多種超載功能,可供您在不同情況下使用,甚至能與任何 UI 架構搭配使用。如要進一步瞭解這些超載,請參閱參考說明文件。
其他資訊
如需詳細資訊,請參閱以下頁面: