我正在构建的应用程序使用具有路由的Compose导航。挑战在于起始点是动态的。
这里是一个简单的示例:
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"
}
}
应用程序崩溃并显示以下信息:
java.lang.IllegalArgumentException: navigation destination route/1 is not a direct child of this NavGraph
只有在使用“动态”路由作为起始目的地时才存在问题。可以通过使用
startDestination =“ static”
来验证。虽然“静态”路线的解决方法有效,但我正在寻找一种无需它的解决方案,因为它会使代码变得混乱不清,并且还会在后向堆栈中创建一个额外的条目。
-> 完整的代码示例以重现该问题
相关SO问题
- Navigation Architecture Component-向startDestination传递参数数据 - 回答似乎不适用于Compose Navigation。 - 在Jetpack Compose中将参数传递给嵌套的导航图 - 没有给出答案。 - Compose Navigation-导航目标...不是此NavGraph的直接子代 - 接受的答案无法解决问题。 编辑: 我要强调原始示例并未包含“静态”组合。我只添加了“静态”组合以获得可工作的
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!")
}
}
导致异常。
java.lang.IllegalArgumentException: navigation destination dynamic is not a direct child of this NavGraph
static
调用navController.navigate("dynamic/1")
,而是直接调用动态场景下的真实内容组合,将"1"
作为硬编码值传递进去,而不是从参数Bundle
中获取。这样可以避免在后退栈中出现额外的条目,并且看起来并不特别复杂。 - CommonsWarenavController.navigate("dynamic/1")
以及您将设置为startDestination
的内容? - Peter FstartDestination
中使用的字符串"dynamic"
需要与您在可组合的route
中使用的确切字符串一一匹配,即"dynamic?$ARG_ID={$ARG_ID}"
。 - ianhanniballakestartDestination
需要是一个具体的路由(包含参数的值)。如果那是可能的,那不是一个很酷的功能吗?那么,参数就不需要默认值,可以被声明为真正必需的。 - Peter F