Pet*_*r F 29 android android-jetpack-navigation android-jetpack-compose android-navigation-graph
我正在构建的应用程序使用带有路线的组合导航。挑战在于起始目的地是动态的。
这是一个最小的例子:
class MainActivity : ComponentActivity()
{
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContent {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = "dynamic/1", // doesn't work
// startDestination = "static", // workaround
) {
composable(
route = "dynamic/{$ARG_ID}",
arguments = listOf(navArgument(ARG_ID) { type = NavType.StringType }),
) {
val id = it.arguments?.getString(ARG_ID)
Text("dynamic route, received argument: $id!")
}
// part of the workaround
// composable(
// route = "static",
// ) {
// LaunchedEffect(this) {
// navController.navigate("dynamic/1")
// }
// }
}
}
}
companion object
{
const val ARG_ID = "id"
}
}
Run Code Online (Sandbox Code Playgroud)
该应用程序崩溃了
java.lang.IllegalArgumentException: navigation destination route/1 is not a direct child of this NavGraph
Run Code Online (Sandbox Code Playgroud)
仅当“动态”路线用作起始目的地时,该问题才存在。这可以通过使用来验证startDestination = "static"。
虽然“静态”路由解决方法有效,但我正在寻找一种没有它的解决方案,因为它会混淆代码,并且还会在返回堆栈中创建一个附加条目。
->重现问题的完整代码示例
相关问题
编辑:
我想强调的是,原始示例过去不包含“静态”可组合项。startDestination我仅添加了“静态”可组合项,以便可以正常工作并证明可以导航到“动态”可组合项。
更新:
即使切换到可选参数的查询参数语法、提供默认值以及设置不带任何参数的起始目标也不起作用。
以下变体
NavHost(
navController = navController,
startDestination = "dynamic",
) {
composable(
route = "dynamic?$ARG_ID={$ARG_ID}",
arguments = listOf(navArgument(ARG_ID) { type = NavType.StringType; defaultValue = "1" }),
) {
val id = it.arguments?.getString(ARG_ID)
Text("dynamic route, received argument: $id!")
}
}
Run Code Online (Sandbox Code Playgroud)
导致异常
java.lang.IllegalArgumentException: navigation destination dynamic is not a direct child of this NavGraph
Run Code Online (Sandbox Code Playgroud)
Pet*_*r F 47
完全归功于ianhanniballake,他在评论中向我解释了解决方案。我将在这里展示我的代码示例的工作版本。
对我来说最重要的见解是:
startDestination不能route与模式匹配意义上的可组合项匹配,但它必须是完全相同的字符串。
这意味着不能startDestination直接通过参数设置参数,而必须通过参数的defaultValue.
这是工作示例:
class MainActivity : ComponentActivity()
{
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContent {
val navController = rememberNavController()
NavHost(
navController = navController,
// 1st change: Set startDestination to the exact string of route
startDestination = "dynamic/{$ARG_ID}", // NOT "dynamic/1", provide arguments via defaultValue
) {
composable(
route = "dynamic/{$ARG_ID}",
// 2nd change: Set startDestination argument via defaultValue
arguments = listOf(navArgument(ARG_ID) { type = NavType.StringType; defaultValue = "1" }),
) {
val id = it.arguments?.getString(ARG_ID)
Text("dynamic route, received argument: $id!")
}
}
}
}
companion object
{
const val ARG_ID = "id"
}
}
Run Code Online (Sandbox Code Playgroud)
该方法同样适用于以查询参数形式提供的参数。
老实说,我认为这是一个小限制,因为起始路线现在决定了defaultValue. 我可能想设置不同的defaultValue或根本不设置。然而,在大多数情况下,这应该是最优雅的解决方案。
| 归档时间: |
|
| 查看次数: |
10969 次 |
| 最近记录: |