Navigation 组件提供了一种导航到目的地的简单通用方式。此接口支持一系列上下文和界面框架。例如,您可以将 Navigation 组件与 Compose、View、fragment、activity 甚至自定义界面框架结合使用。
本指南介绍了如何使用 Navigation 组件在各种上下文中导航到目的地。
使用 NavController
您在目的地之间移动时所用的密钥类型是 NavController
。如需详细了解该类本身以及如何创建它的实例,请参阅创建导航控制器。本指南将详细介绍其使用方法。
导航
无论您使用哪种界面框架,都可以使用单个函数导航到目的地:NavController.navigate()
。
有很多重载都适用于 navigate()
。您应选择与您的确切上下文相对应的重载。例如,在转到可组合项时,应该使用一个重载,在导航到视图时使用另一个重载。
以下部分概述了您可以使用的一些关键 navigate()
重载。
导航到可组合项
如需导航到导航图中的可组合项,请使用 NavController.navigate(route)
。使用此重载时,navigate()
带有一个 String
参数。该参数就是 route
。它充当目的地的键。
navController.navigate("friendslist")
如需使用 route
字符串进行导航,您首先需要创建 NavGraph
,以便每个目的地都与 route
相关联。对于可组合项,您可以使用 composable()
函数来实现此目的。
如需了解详情,请参阅导航到目的地。
公开可组合项中的事件
当可组合函数需要导航到新屏幕时,您不应向其传递对 NavController
的引用,以便其直接调用 navigate()
。根据单向数据流 (UDF) 原则,可组合项应改为公开 NavController
处理的事件。
更直接地说,您的可组合项应带有一个类型为 () -> Unit
的参数。
使用 composable()
函数向 NavHost
添加目的地时,向可组合项传递对 NavController.navigate()
的调用。
请参阅以下小节查看这样做的确切示例。
示例
如上一部分所示,在以下代码段中请注意以下要点:
MyAppNavHost
可组合项包含NavController
实例。- 因此,对
navigate()
的调用应该在此处发生,而不是在较低的可组合项(如ProfileScreen
)中发生。 ProfileScreen
包含一个按钮,点击该按钮可将用户转到FriendsList
。不过,它不会调用navigate()
本身。- 相反,该按钮会调用作为
onNavigateToFriends
参数公开的函数。 - 当
MyAppNavHost
将ProfileScreen
添加到导航图时,对于onNavigateToFriends
,它会传递调用navigate()
的 lambda。 - 这样可确保用户在按下按钮
ProfileScreen
时,能够正确导航到friendsList
。
@Composable
fun MyAppNavHost(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
startDestination: String = "profile"
) {
NavHost(
modifier = modifier,
navController = navController,
startDestination = startDestination
) {
composable("profile") {
ProfileScreen(
onNavigateToFriends = { navController.navigate("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()
。不过,该函数有一系列过载,可供您在不同上下文中使用,以及与任何界面框架搭配使用。如需详细了解这些过载,请参阅参考文档。
深入阅读
如需了解详情,请参阅以下页面: