Jetpack Compose Navigation - 将参数传递给 startDestination

2024-06-28

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

这是一个最小的例子:

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".

虽然“静态”路由解决方法有效,但我正在寻找一种没有它的解决方案,因为它会混淆代码,并且还会在返回堆栈中创建一个附加条目。

-> 完整代码示例 https://github.com/p-fischer/compose-navigation-startdestination-with-argument重现问题

相关问题

  • 导航架构组件 - 将参数数据传递到 startDestination https://stackoverflow.com/q/50334550/2011622- 答案似乎不适用于撰写导航。
  • 将参数传递给 Jetpack Compose 中的嵌套导航图 https://stackoverflow.com/q/70086094/2011622- 没有给出答案。
  • Compose Navigation - 导航目的地...不是此 NavGraph 的直接子级 https://stackoverflow.com/q/69038660/2011622- 接受的答案并不能解决问题。

Edit:

我想强调的是,原始示例过去不包含“静态”可组合项。我只添加了“静态”可组合项以获得工作startDestination并证明可以导航到“动态”可组合项。

Update:

甚至切换到可选参数的查询参数语法 https://developer.android.com/jetpack/compose/navigation#optional-args、提供默认值并在不带任何参数的情况下设置起始目标是不起作用的。

以下变体

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

全部功劳归于伊安汉尼巴拉克 https://stackoverflow.com/users/1676363/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或者根本没有。然而,在大多数情况下,这应该是最优雅的解决方案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Jetpack Compose Navigation - 将参数传递给 startDestination 的相关文章

随机推荐

  • asp.net linkbutton onclientclick 和 postback

    当我将 ASP NET LinkBut ton 与 OnClientClick 属性一起使用时 我遇到了一些奇怪的行为 ASPX
  • 阅读共享偏好

    我正在为我的 Android 应用程序的设置菜单使用共享首选项 它工作得很好 但我不知道如何在我的代码中使用这些设置 例如 如何使用所选语言并在另一个活动中使用它
  • 使用张量流 tf-transform 进行数据标准化

    我正在使用 Tensorflow 对我自己的数据集进行神经网络预测 我做的第一个模型是与我计算机中的小数据集一起使用的模型 之后 我稍微更改了代码 以便使用具有更大数据集的 Google Cloud ML Engine 在 ML Engin
  • 使用 Auth0、withAuthenticationRequired 登录不会显示在 Gatsby 中

    我将 Gatsby 与 auth0 一起使用 当我用withAuthenticationRequired 然后我得到一个空白页 上面写着 重定向 import as React from react import withAuthentic
  • Python:pip 找不到 setup.py

    我怎样才能直接pip找到setup py My setup py文件位于 setuptools 3 5 1 I ran dustin dustin python setuptools 3 5 1 setup py egg info runn
  • 以编程方式添加超链接到列表项

    我想以编程方式获得以下 HTML ul li a href a li ul 我可以添加 li to ul But a to li 不可能 My code BulletedList ul new BulletedList ListItem l
  • React Table - useRowSelect 的单选输入

    如何在 React Table 中使用单选输入而不是复选框作为可选表 有一个复选框但没有单选按钮的示例 https github com tannerlinsley react table blob master examples row
  • 无法访问内存-gdb

    这是我的disas代码 Dump of assembler code for function main 0x00000000000006b0 lt 0 gt push rbp 0x00000000000006b1 lt 1 gt mov
  • Java进程的dump文件分析?

    如果我使用 Windbg 转储 Windows 上运行的 Java 进程 我可以 容易吗 分析 Java 堆 对象和线程吗 就像我可以使用 SOS 进行 Net 进程一样吗 否则 如何离线调试生产系统上发生的问题 Thanks Window
  • 等待异步TaskEx

    What is TaskEx In http www i programmer info programming c 1514 async await and the ui problem html start 1 http www i p
  • 类型错误:序列项 0:预期字符串,未找到 NoneType

    我正在努力改进战舰游戏 原始版本工作正常 没有错误 我编写了代码来帮助克服第一个版本每次都将船只放置在同一个位置的事实 因此我从一艘船 由两个方块组成 开始 我通过创建两个函数来完成此操作 第一个函数生成一个随机坐标 Destroyer 2
  • catch(...) 没有捕获异常,我的程序仍然崩溃

    我的测试仪遇到问题 我的应用程序在初始化时崩溃 我添加了更多的日志记录和异常处理 但它仍然崩溃并显示通用的 此程序已停止工作 消息 而不是触发我的错误处理 鉴于我的 main 看起来像这样并且有catch 什么情况下不会触发 try sim
  • Collectors.groupingBy() 返回按升序排序的结果 java

    我按降序发送结果 但得到的输出按升序排列 List
  • 如何使用RxJsdistinctUntilChanged?

    我正在开始使用 RxJs 使用 v5 beta 但不知何故我不知道如何使用distinctUntilChanged 如果我在 babel node 中运行下面的代码 其输出是 a 1 key a state 1 Next value 42
  • Boto 与 EC2 IAM 角色间歇性“无法加载凭证”

    我使用 Elastic Beanstalk 环境来部署 Web 应用程序 并为应用程序将在其上运行的实例设置了 IAM 角色 99 99 的时间里一切都完美无缺 但是我会间歇性地在日志中看到错误 请求失败显示 botocore 错误 如下所
  • Python - 比较2个文件并输出差异

    我的目标是编写一个脚本来比较文件中的每一行 并根据此比较创建一个新文件 其中包含第二个文件中不存在的文本行 例如 File 1 Bob 20 Dan 50 Brad 34 Emma 32 Anne 43 File 2 Dan 50 Emma
  • SQL Server 2008:TOP 10 和不同的一起

    正如标题所示 我正在使用 SQL Server 2008 如果这个问题非常基本 我深表歉意 我才使用 SQL 几天 现在我有以下查询 SELECT TOP 10 p id pl nm pl val pl txt val from dm la
  • excel vba范围单元格错误对象定义[重复]

    这个问题在这里已经有答案了 我一直在 Excel 中开发一个宏 该宏对一张工作表 次要 中的表格进行排序 当满足条件时 它应该将该表中的数据添加到第二张工作表 Sheet1 中的另一个表格中 但是我一直运行时出现 1004 错误 对象未定义
  • 需要更好的等待解决方案

    最近 我一直在用 C 编写一个程序 它可以 ping 三个不同的网站 然后根据通过或失败的情况 它将等待 5 分钟或 30 秒 然后再次尝试 目前我一直在使用ctime库和以下函数来处理我的等待 然而 根据我的 CPU 计量表 这是一个不可
  • Jetpack Compose Navigation - 将参数传递给 startDestination

    我正在构建的应用程序使用带有路线的组合导航 挑战在于起始目的地是动态的 这是一个最小的例子 class MainActivity ComponentActivity override fun onCreate savedInstanceSt