1

我使用 SafeArgs 很好地设置了我的应用程序的主导航。这是我的nav_graph.xml

<navigation
    android:id="@+id/nav_main"
    app:startDestination="@+id/fragment1">

    <fragment
        android:id="@+id/fragment1"
        android:name="org.example.Fragment1"
        android:label="Fragment 1">

        <action
            android:id="@+id/fragment1_to_fragment2"
            app:destination="@id/fragment2" />

    </fragment>

    <fragment
        android:id="@+id/fragment2"
        android:name="org.example.Fragment2"
        android:label="Fragment 2">
        
        <argument
            android:name="ARG_CATEGORY_ID"
            app:argType="long"/>

        <action
            android:id="@+id/fragment2_to_fragment3"
            app:destination="fragment3" />
            
    </fragment>

    <fragment
        android:id="@+id/fragment3"
        android:name="org.example.Fragment3"
        android:label="Fragment 3">
        
        <argument
            android:name="ARG_ITEM_ID"
            app:argType="long"/>
        
   </fragment>

</navigation>

而且,使用 SafeArgs,我可以愉快地使用以下命令从Fragment2导航到Fragment3

NavDirections navDirections = Fragment2Directions.fragment2ToFragment3(myItemId);
navController.navigate(navDirections);

但是,我随后需要从通知中添加深度链接功能(有一个带有参数的 backstack ,如此处所述),所以我在nav_graph.xml<navigation />的末尾添加了一个子元素——它变成了:

<navigation
    android:id="@+id/nav_main"
    app:startDestination="@+id/fragment1">

    <fra8gment
        android:id="@+id/fragment1"
        android:name="org.example.Fragment1"
        android:label="Fragment 1">

        <action
            android:id="@+id/fragment1_to_fragment2"
            app:destination="@id/fragment2" />

    </fragment>

    <fragment
        android:id="@+id/fragment2"
        android:name="org.example.Fragment2"
        android:label="Fragment 2">
        
        <argument
            android:name="ARG_CATEGORY_ID"
            app:argType="long"/>

        <action
            android:id="@+id/fragment2_to_fragment3"
            app:destination="fragment3" />
            
    </fragment>

    <fragment
        android:id="@+id/fragment3"
        android:name="org.example.Fragment3"
        android:label="Fragment 3">
        
        <argument
            android:name="ARG_ITEM_ID"
            app:argType="long"/>
        
    </fragment>
   
    <!-- This is the new sub navigation block that provides a backstack-with-arguments. -->
    <navigation
        android:id="@+id/nav_notification"
        app:startDestination="@id/fragment2Notif">

        <fragment
            android:id="@+id/fragment2Notif"
            android:name="org.example.Fragment2"
            android:label="Fragment 2">

            <action
                android:id="@+id/fragment2Notif_to_fragment3Notif"
                app:destination="@id/itemsGraph" />

        </fragment>

        <navigation
            android:id="@+id/itemsGraph"
            app:startDestination="@id/fragment3Notif">

            <argument
                android:name="ARG_ITEM_ID"
                app:argType="long"/>

            <fragment
                android:id="@+id/fragment3Notif"
                android:name="org.example.Fragment3"
                android:label="Fragment 3">

                <argument
                    android:name="ARG_ITEM_ID"
                    app:argType="long"/>

            </fragment>

        </navigation>
        
    </navigation>
   
</navigation>

请注意,该文件现在包含两次出现的org.example.Fragment2.

这给我带来了一个新问题,即第二次出现org.example.Fragment2(即fragment2Notif)导致原来的Fragment2Directions.fragment2ToFragment3(...)方法不再可用。

它已被替换为Fragment2Directions.fragment2NotifToFragment3Notif(...)在我的应用程序的通知部分中可以正常工作,但是当从我的应用程序的主要部分调用时,如预期的那样,会导致:

IllegalArgumentException:导航目的地 org.example:id/fragment2Notif_to_fragment3Notif 对此 NavController 未知

似乎 SafeArgs 已经覆盖了第一个Fragment2Directions对象,这意味着它拥有的唯一方法是fragment2NotifToFragment3Notif(...).

那么,如何fragment2ToFragment3(...)恢复旧方法呢?

我希望我可以通过将 Fragment2 子类化以使用不同的名称 Fragment2Notif 有效地复制它,然后在我的主导航中使用 Fragment2 并在子导航中使用 Fragment2Notif 来解决问题但是有更优雅/首选的方式吗?

4

1 回答 1

0

查看您的nav_graph.xml文件,我认为嵌套图(在父导航图中分组的一系列目的地,在本例中为 id nav_main)的想法是从通知中添加深度链接功能(具有带参数的回栈)。

除此之外,假设SafeArgs插件fragment2ToFragment3(...)覆盖 了标签。fragment2NotifToFragment3Notif(...)Fragment3fragment2NotifToFragment3Notif(...)<fragment>

因此,本质上使用fragment2NotifToFragment3Notif(...)代替fragment2ToFragment3(...)不会对这种情况造成伤害。

于 2020-07-07T15:25:17.113 回答