如何将 NavArgs 映射到 NavArgument?

How to map NavArgs to NavArgument?

我遇到的问题与以编程方式设置导航图有关。我想要实现的是在 Activity 中决定哪个片段应该是起始目的地。更重要的是,这些片段中的每一个都有额外的参数。

假设我们有这样的导航图:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph">

    <fragment
        android:id="@+id/fragment1"
        android:name="com.mypackage.Fragment1"
        tools:layout="@layout/layout_fragment1">

        <argument
            android:name="argument1"
            app:argType="int" />

    </fragment>

    <fragment
        android:id="@+id/fragment2"
        android:name="com.mypackage.Fragment2"
        tools:layout="@layout/layout_fragment2">

        <argument
            android:name="argument2"
            app:argType="string" />

    </fragment>

</navigation>

如果我们使用 Safe Args 插件 (androidx.navigation.safeargs.kotlin),将生成两个 类:Fragment1ArgsFragment2Args,它们都实现了 NavArgs 接口。

现在因为我们需要决定哪个片段应该成为起始目的地,所以我们需要以编程方式制作图表:

val graph = navController.navInflater.inflate(R.navigation.nav_graph)
if (someCondition) {
    graph.startDestination = R.id.fragment1
} else {
    graph.startDestination = R.id.fragment2
}
navController.graph = graph

但是 Fragment1 和 Fragment2 需要一些额外的参数,所以我们需要以某种方式将它们添加到图形中。事实证明该图具有方法 addArguments(NavArguments),但如您所见,它不是 NavArgs 接口。问题是如何正确设置 Fragment1 或 Fragment2 能够提取的这些参数?

我正在使用 1.0.0-rc02 版本的导航框架。

你说:"What I want to achieve is to decide in Activity which fragment should be a start destination."

而且我认为你正试图在片段中做出决定,这在这里是不正确的,因为你还没有打开片段,因此正确的行为是在 activity 中这样做,例如:

when (someCondition) {
        TO_FRAGMENT_1-> {
            findNavController(R.id.fragment).navigate(R.id.fragment1)
        }
        TO_FRAGMENT_2-> {
            findNavController(R.id.fragment).navigate(R.id.fragment2)
        }
    }

并且如果 activity 是您应用中的第一个 activity,您应该使用其他东西代替 args,例如:SharedPref.

当您将 <argument> 标记添加到您的导航 XML 时,它 已经 创建 NavArgument 类 当您调用 inflate(),因此您无需对图形执行任何操作即可将参数传递到起始目的地。

相反,您应该使用 setGraph(NavGraph, Bundle) 来设置图表并将初始参数传递到起始目的地。

// Construct your Bundle of arguments
val bundle = bundleOf()
// set the graph with specific arguments for the start destination
navController.setGraph(graph, bundle)