Jetpack合成导航-将参数传递给startDestination [英] Jetpack Compose Navigation - pass argument to startDestination

本文介绍了Jetpack合成导航-将参数传递给startDestination的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建的应用程序使用带有路线的组合导航。挑战在于起始目标是动态的。

这里是一个最小的示例:

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"进行验证。

虽然";静态";路由解决方法可行,但我正在寻找不使用它的解决方案,因为它会混淆代码,还会在后端堆栈中创建一个额外的条目。

->;Full code sample复制问题

相关SO问题

编辑:

我想强调的是,原始样本过去不包含";静态&可组合。我添加";静态";Composable只是为了让startDestination正常工作,并证明可以导航到";Dynamic";Composable。

更新:

即使切换到query parameter syntax for optional arguments、提供默认值并在没有任何参数的情况下设置开始目标也不起作用。

以下变体

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

推荐答案

全部归功于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"
    }
}

该方法同样适用于以查询参数形式提供的参数。

老实说,我认为这是一个很小的限制,因为开始路线现在规定了必须是defaultValue。我可能希望设置不同的defaultValue或根本不设置。然而,在大多数情况下,这应该是最优雅的解决方案。

这篇关于Jetpack合成导航-将参数传递给startDestination的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆