You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用NavController通过DeepLink Uri跳转时传递Bundle参数?

问题描述

我想实现如下功能:

void nav(NavController navController, Uri deepLink, Bundle args) {
    navController.navigate(deepLink, args);
}

但androidx.navigation.NavController仅提供navigate(Uri deepLink)以及navigate(int resId, Bundle args)等重载方法,并没有navigate(Uri deepLink, Bundle args)方法。请问有没有办法在通过Uri DeepLink跳转至未知Fragment时传递Bundle参数?

比如,如果能通过DeepLink获取目标Fragment的资源ID,就可以调用navController.navigate(resID, args)来实现需求。

背景

我在单Activity应用中使用NavController实现Fragment间跳转,这些Fragment分布在多个模块中,对应不同的nav_graph。DeepLink是通过配置文件中的字符串动态生成,或由服务器下发,格式为类似"{module}://start{name}"的标准形式。部分Fragment需要了解自身的调用来源信息,但大部分不需要,而调用端无法区分两者。

我希望找到一种简洁的方式实现navigate(Uri, Bundle)的功能,已知一些不太优雅的方案(比如修改所有nav_graph添加大部分模块/Fragment不会使用的可选"safeargs"参数,或者将参数Bundle存入全局可访问位置让Fragment在onCreate中获取),但非常希望避免这类方案。

可行解决方案

1. 通过DeepLink匹配获取目标Destination的ID

遍历NavController导航图中的所有节点,匹配对应的DeepLink,找到目标Destination的ID后调用带Bundle的重载方法:

void nav(NavController navController, Uri deepLink, Bundle args) {
    // 遍历全局导航图的所有节点,匹配DeepLink
    for (NavDestination destination : navController.getGraph().getNodes()) {
        boolean isMatch = destination.getDeepLinks().stream()
                .anyMatch(deepLinkItem -> deepLinkItem.matches(deepLink));
        if (isMatch) {
            navController.navigate(destination.getId(), args);
            return;
        }
    }
    // 未匹配到目标节点时,降级调用默认DeepLink跳转
    navController.navigate(deepLink);
}

注意:多模块场景下,需要确保所有模块的nav_graph都已被添加到NavController的全局导航图中,否则会出现匹配失败的情况。

2. 封装扩展函数简化调用

把上述匹配逻辑封装成NavController的扩展函数,让调用形式和你最初期望的完全一致:

fun NavController.navigate(deepLink: Uri, args: Bundle) {
    val targetDest = graph.nodes.find { dest ->
        dest.deepLinks.any { it.matches(deepLink) }
    }
    targetDest?.let { navigate(it.id, args) } ?: navigate(deepLink)
}

调用时直接使用navController.navigate(deepLink, args)即可。

3. 利用NavOptions临时传递参数(非官方推荐)

通过NavOptions的setArguments()方法携带参数,目标Fragment可通过getArguments()获取:

void nav(NavController navController, Uri deepLink, Bundle args) {
    NavOptions options = new NavOptions.Builder()
            .setArguments(args)
            .build();
    navController.navigate(deepLink, options);
}

注意:如果目标Destination本身通过DeepLink传递了同名参数,NavOptions中的参数会覆盖前者,仅适用于无参数冲突的场景。

内容的提问来源于stack exchange,提问作者Jordi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 14:32:15