首页 > 解决方案 > 使用 view pager2 和嵌套导航正确使用导航组件

问题描述

我正在尝试使用 ViewPager2 + FragmentStateAdapter + 导航组件构建以下视图结构/导航。

前提条件:单一活动架构,带有一个导航图

1. Fragment A持有一个视图寻呼机。View pager 使用 FragmentStateAdapter。

2. Fragment B通过 FragmentStateAdapter 实例化(“生活”在视图寻呼机中)。

3. Fragment C - 应该从 Fragment B 导航到。 --> 这就是问题所在。


方法 1:ViewPager2 + FragmentStateAdapter + 从 Fragment B 声明的导航

    <fragment
        android:id="@+id/fragmentA"
        android:name="com.abc.FragmentA"
        android:label="FragmentA" />

    <fragment
        android:id="@+id/fragmentB"
        android:name="com.abc.FragmentB"
        android:label="FragmentB">
        <action
            android:id="@+id/to_fragmentC"
            app:destination="@id/fragmentC" />
    </fragment>

    <fragment
        android:id="@+id/fragmentC"
        android:name="com.abc.FragmentC"
        android:label="FragmentC" />

片段B执行:

 FragmentBDirections
            .toFragmentC()
            .let { findNavController().navigate(it) }

结果 :

App crash
java.lang.IllegalArgumentException: navigation destination com.abc:id/to_fragmentC is unknown to this NavController

方法 2:ViewPager2 + FragmentStateAdapter + 从 Fragment A 声明的导航

    <fragment
        android:id="@+id/fragmentA"
        android:name="com.abc.FragmentA"
        android:label="FragmentA" >
        <action
            android:id="@+id/to_fragmentC"
            app:destination="@id/fragmentC" />
    </fragment>

    <fragment
        android:id="@+id/fragmentB"
        android:name="com.abc.FragmentB"
        android:label="FragmentB">
    </fragment>

    <fragment
        android:id="@+id/fragmentC"
        android:name="com.abc.FragmentC"
        android:label="FragmentC" />

片段B执行:

 FragmentADirections
            .toFragmentC()
            .let { findNavController().navigate(it) }

结果:

App navigates to FragmentC, but when i hit the back button , it crashes with :
java.lang.IllegalArgumentException
        at androidx.core.util.Preconditions.checkArgument(Preconditions.java:36)
        at androidx.viewpager2.adapter.FragmentStateAdapter.onAttachedToRecyclerView(FragmentStateAdapter.java:132)
        at androidx.recyclerview.widget.RecyclerView.setAdapterInternal(RecyclerView.java:1209)
        at androidx.recyclerview.widget.RecyclerView.setAdapter(RecyclerView.java:1161)
        at androidx.viewpager2.widget.ViewPager2.setAdapter(ViewPager2.java:461)
        at com.abc.FragmentA.viewCreated(FragmentA.kt:69)


方法 3:ViewPager + FragmentStatePagerAdapter(已弃用)+ 从 Fragment B 声明的导航

结果与方法 1 相同。


方法 4:ViewPager + FragmentStatePagerAdapter(已弃用)+ 从 Fragment A 声明的导航

这个确实有效。此外,导航返回工作正常。

这里的问题是:

如果有人知道这个问题的一些优雅的解决方案,我会很高兴任何提示。

谢谢

标签: androidandroidxandroid-architecture-navigation

解决方案


您不需要将 Fragment B 声明为图形中的目的地,因为您从不使用 NavController 导航到它。您可以在 Fragment B 中使用目的地 id来实现导航,而不是使用操作,例如findNavController().navigate(R.id.fragmentC). 该findNavController方法会找到父片段的 navController 来执行导航。


推荐阅读