Navigation 元件提供簡單且通用的方式,可前往目的地。這個介面適用於多種情況和 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 架構搭配使用。如要進一步瞭解這些超載,請參閱參考說明文件。
其他資訊
如需詳細資訊,請參閱以下頁面: