简体   繁体   English

使用导航组件将参数安全地传递给嵌套图

[英]Pass arguments safely to nested graph with Navigation Component

I'm using Android Jetpack Navigation Component.我正在使用 Android Jetpack 导航组件。 I have a nested nav graph with id, say R.id.nested_graph The first Fragment of the nested graph receives one parameter.我有一个带有 id 的嵌套导航图,比如R.id.nested_graph嵌套图的第一个Fragment接收一个参数。

<navigation
        android:id="@+id/nested_graph"
        android:label="Nested Graph"
        app:startDestination="@id/firstFragment">
        <fragment
            android:id="@+id/firstFragment"
            android:name="...."
            android:label="....">
            <argument
                android:name="item_id"
                app:argType="integer" />
        </fragment>
        [...]
    </navigation>

How can I pass the parameter to the nested graph using safe args ?如何使用安全 args将参数传递给嵌套图?

At the moment, I need to pass the argument manually in the bundle, using the API that receives the id of the nested graph directly:目前,我需要在包中手动传递参数,使用直接接收嵌套图的 id 的 API:

        val args = Bundle()
        args.putInt("item_id", itemId)
        navController.navigate(R.id.nested_graph, args)

I'd like to use safe args, and do something like:我想使用安全参数,并执行以下操作:

        val directions = OrigininFragmentDirections.nestedGraph(itemId)
        navController.navigate(directions)

But when trying that, I get the following error at build time:但是在尝试时,我在构建时收到以下错误:

Too many arguments for public final fun nestedGraph(): NavDirections defined 

The issue is that the nav graph preprocessing is generating the factory method to create the NavDirections object without the required parameter in the signature.问题是导航图预处理正在生成工厂方法来创建NavDirections对象,签名中没有必需的参数。

The declaration of the nested graph looks like this:嵌套图的声明如下所示:

After some trial and error experimentation (I don't think it's officially documented by Google, or at least I could not find it), I've discovered that navigating to nested nav graphs passing arguments safely can be done:经过一些反复试验(我认为谷歌没有正式记录,或者至少我找不到它),我发现可以安全地导航到嵌套的导航图传递参数:

You need to add the argument XML object the first fragment expects in the root of the nested fragment itself.您需要在嵌套片段本身的根中添加第一个片段所需的argument XML 对象。

In my case, the fragment with id firstFragment , which is the first fragment in the nested graph receives:在我的例子中,带有 id firstFragment的片段,它是嵌套图中的第一个片段接收:

            <argument
                android:name="item_id"
                app:argType="integer" />

Hence, I need to add that argument to the nested graph:因此,我需要将该参数添加到嵌套图中:

<navigation
        android:id="@+id/nested_graph"
        android:label="Nested Graph"
        app:startDestination="@id/firstFragment">

            <argument
                android:name="item_id"
                app:argType="integer" />

        <fragment
            android:id="@+id/firstFragment"
            android:name="...."
            android:label="....">
            <argument
                android:name="item_id"
                app:argType="integer" />
        </fragment>
        [...]
    </navigation>

Now I can navigate to it with:现在我可以导航到它:

   val directions = OrigininFragmentDirections.nestedGraph(itemId)
        navController.navigate(directions)

Note that the navigation graph editor does not do it for you.请注意,导航图编辑器不会为您执行此操作。 This needs to be done manually in the XML code.这需要在 XML 代码中手动完成。

@GaRRaPeTa answer is almost correct, but if you navigate from main graph to nested graph by action using SafeArgs, you must also add an argument to the action: @GaRRaPeTa 答案几乎是正确的,但是如果您使用 SafeArgs 通过操作从主图导航到嵌套图,则还必须向操作添加参数:

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/graph_main"
    app:startDestination="@id/mainFragment">

    <fragment
        android:id="@+id/mainFragment"
        android:name="com.example.MainFragment">

        <action
            android:id="@+id/toNestedGraph"
            app:destination="@id/graph_nested">

            <argument
                android:name="arg_name"
                app:argType="string" />
        </action>
    </fragment>

</navigation>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM