昨天提到 NavHost
負責定義所有可導航的畫面,NavController
則負責管理應用中的導航行為。除了單純的畫面跳轉外,Compose Navigation 還支持帶參數的導航方式。今天將介紹傳遞參數以及 Deeplink 功能,幫助我們在導航時處理更複雜的情境。
那如何在跳轉時帶參數,主要的做法是在NavHost的路徑中加入預留位置。透過arguments
來定義我們傳遞的參數,接著透過navArgument
來定義名稱以及資料型態。
我們這邊建立兩個畫面分別是 login
以及 home/{text}
,並且在 home 中定義 text 的資料型態以及 HomeScreen 的參數。
@Composable
fun MainScreen(modifier: Modifier = Modifier) {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "login") {
composable("login") { LoginScreen(navController = navController, modifier = modifier) }
composable(
route = "home/{text}",
arguments = listOf(
navArgument("text") {
type = NavType.StringType
}
)
) {
HomeScreen(navController, it.arguments?.getString("text"), modifier)
}
}
}
在使用上我們只需在使用 navigate
加上傳遞參數即可達成。
@Composable
fun LoginScreen(navController: NavController, modifier: Modifier) {
val text = remember { mutableStateOf("") }
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
.width(200.dp)
.padding(16.dp)
) {
Text("Login Screen")
TextField(
value = text.value,
onValueChange = {
text.value = it
},
modifier = modifier.padding(16.dp)
)
Button(onClick = { navController.navigate("home/${text.value}") }) {
Text("Login")
}
}
}
HomeScreen 的處理
@Composable
fun HomeScreen(navController: NavController, name: String?, modifier: Modifier) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
.width(200.dp)
.padding(16.dp)
) {
Text("Hello ${name ?: ""}")
}
}
DeepLink 的做法跟上面大同小異,只需要透過 deepLinks
來定義我們傳遞的參數,接著透過navDeepLink
來定義名稱。
composable(
route = "login/{name}",
deepLinks = listOf(
navDeepLink {
uriPattern = "URI/{name}"
}
)
) {
HomeScreen(navController, it.arguments?.getString("name"), modifier)
}