导航组件 - ViewPager 碎片中的 findNavController 无法工作

6
我有一个包含3个菜单选项(主页、服务和更多)的BottomNavigation。 主页选项卡片段包含TabLayout和ViewPager。
ViewPager有2个片段 - CurrentDetailFargment和PreviousDetailFragment。
ViewPager有效,之后当我使用findNavController()点击CurrentDetailFargment按钮时,我会收到异常。 参考 导航付款屏幕
findNavController().
navigate(R.id.action_currentBillFragment_to_paymentOptionsFragment)

异常

java.lang.IllegalArgumentException: navigation destination XXXXXXX:id/action_currentBillFragment_to_paymentOptionsFragment is unknown to this NavController
    at androidx.navigation.NavController.navigate(NavController.java:789)
    at androidx.navigation.NavController.navigate(NavController.java:730)
    at androidx.navigation.NavController.navigate(NavController.java:716)
    at androidx.navigation.NavController.navigate(NavController.java:704)
    at com.bses_yamuna.user.home.currentbill.view.CurrentBillFragment.navigateToPayNow

根据异常情况 - 我在我的图表中没有提到“action_currentBillFragment_to_paymentOptionsFragment” ID。但是我已经在图表中声明了它。这个图表与底部导航一起使用。
请告诉我如何解决这个问题。
活动布局部分 -
    <fragment
        android:id="@+id/navigationHost"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@+id/bottomNavigation"
        app:layout_constraintTop_toBottomOf="@+id/constraint_top"
        app:navGraph="@navigation/menu_navigation" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNavigation"
        style="@style/Widget.BottomNavigationView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:attr/windowBackground"
        app:itemIconTint="@drawable/bottom_navigation_item_colors"
        app:itemTextColor="@drawable/bottom_navigation_item_colors"
        app:labelVisibilityMode="labeled"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu_modify" />

Adapter

 class ViewPagerAdapter (fragmentManager:FragmentManager, private val titleList: ArrayList<String>): FragmentStatePagerAdapter(fragmentManager,BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT ) {

override fun getItem(position: Int): Fragment {
    return if(position==0)
        CurrentBillFragment()
    else
        PreviousBillFragment()

}

override fun getCount(): Int {
   return titleList.size
}

override fun getPageTitle(position: Int): CharSequence? {
    return titleList[position]
}
override fun getItemPosition(value: Any): Int {
    return PagerAdapter.POSITION_NONE
}

}

在ViewPager上设置适配器-

private fun setupViewPager() {
    val titles = ArrayList<String>()
    titles.add(getString(R.string.current_bill_detail))
    titles.add(getString(R.string.previous_bill_detail))
    val adapter = ViewPagerAdapter(childFragmentManager, titles)
    mBinding.tabLayout.setupWithViewPager( mBinding.pager)
    mBinding.pager.adapter = adapter

}

menu_navigation.xml-

   <fragment
    android:id="@+id/currentBillFragment"
    android:name="XXXXX.view.CurrentDetailFargment "
    tools:layout="@layout/fragment_current_bill">

    <action          
  android:id=
  "@+id/action_currentBillFragment_to_currentBillSummaryFragment"
        app:destination="@+id/currentBillSummaryFragment" />

</fragment>
<fragment
    android:id="@+id/paymentOptionsFragment"
    android:name="XXXXX.view.PaymentOptionsFragment"
    tools:layout="@layout/fragment_payment_option"/>

你解决了吗,@Mukesh? - Rethinavel
3个回答

5

应该在包含 ViewPager 和 TabLayout 的片段中定义操作。

我将动作“action_currentBillFragment_to_currentBillSummaryFragment”移到了 ViewPager 和 TabLayout 的宿主片段中。


是的,它是有效的,但实际上,我在想这是否是正确的方式...有时我认为直接通过ID导航可能更好,因为这可能会让人感到困惑。 - imansdn

1
我也遇到了同样的问题,并发现我们在navigation_graph XML文件中采取了错误的方向操作。导航动作方向应该是从homeFragment到PaymentOptoinFragment,而不是从currentDetailFragment到paymentOptionFragment。previousDetailFragment同理。
navigation_graph XML文件中的导航方向:

navigation_graph

从CurrentDetailFragment和PrevoiusDetailFragment导航到paymentOptionsFragment的Kotlin代码:

   //Navigation from CurrentDetailFragment to paymentOptionsFragment
this.@CurrentDetailFragment.findNavController().
navigate(R.id.action_HomeFragment_to_paymentOptionsFragment)

//Navigation from PrevoiusDetailFragment to paymentOptionsFragment   
this.@PrevoiusDetailFragment.findNavController().
navigate(R.id.action_HomeFragment_to_paymentOptionsFragment)

尝试这个,让我知道你是否仍然遇到相同的问题!

我有完全相同的问题,从homeFragment到paymentOptionFragment导航正常工作,但是我想在单击这两个片段中的任何小部件后,从currentDetailFragment或previousDetailFragment导航到paymentOptionFragment。 - Shubham Mogarkar
嗨@ShubhamMogarkar,我已经在上面提到了解决方案。你是否按照这个步骤进行了操作?另一件事是,请问您在项目中使用的是哪种编程语言?以及导航代码? - Md. Shohag Ali Sarder
是的,我正在使用 Kotlin。我找到了解决方案,我会在答案中发布。 - Shubham Mogarkar

0

这段代码是用于Kotlin的

确保在FragmentStateAdapter中传递childFragmentManager,如下所示的代码。

class AdapterTabPager(childFragmentManager: FragmentManager, lifecycle: Lifecycle) : FragmentStateAdapter(childFragmentManager, lifecycle) {
   
}

现在将这段代码编写到您的viewPager片段中。

val yourViewPagerContainerFragment = (this.parentFragment as YourViewPagerContainerFragment )
        yourViewPagerContainerFragment.access_anything_from_view_pager_container_fragment

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接