mukesh
mukesh

Reputation: 4140

Navigation Component - findNavController from ViewPager fragment not work

I have a BottomNavigation with 3 menu option(Home,Service and More). Home tab fragment contains TabLayout and ViewPager.

ViewPager has 2 fragment - CurrentDetailFargment and PreviousDetailFragment.

ViewPager Works, After that when I applied click on Button of CurrentDetailFargment using findNavController() then I get exception.

Reference

Navigate Payment Screen

findNavController().
navigate(R.id.action_currentBillFragment_to_paymentOptionsFragment)

Exception

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

According to exception - I had not mention 'action_currentBillFragment_to_paymentOptionsFragment' id in my graph. But I had declare it graph. This graph is use with BottomNaviagtion.

Please Let me know that I resolve this issues.

Activity Layout Section-

    <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
}

}

Set Adapter on 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"/>

Upvotes: 6

Views: 4304

Answers (3)

Shubham Mogarkar
Shubham Mogarkar

Reputation: 263

This Code is for kotlin

Make sure that you pass childFragmentManager in the FragmentStateAdapter, as below code.

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

Now write this code into your viewPager's fragment.

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

Upvotes: 0

Md Shohag Ali Sarder
Md Shohag Ali Sarder

Reputation: 21

I have also faced the same issue and figured out that we are making the wrong direction action in the navigation_graph XML file. The navigation action direction should be from homeFragment to PaymentOptoinFragment. Not from the currentDetailFragment to paymentOptionFragment. The same goes for the previousDetailFragment.

Navigation direction in the navigation_graph XML file:

navigation_graph

Kotlin Code to navigate paymentOptionsFragment from CurrentDetailFragment and PrevoiusDetailFragment:

   //Navigation from CurrentDetailFragment to paymentOptionsFragment
[email protected]().
navigate(R.id.action_HomeFragment_to_paymentOptionsFragment)

//Navigation from PrevoiusDetailFragment to paymentOptionsFragment   
[email protected]().
navigate(R.id.action_HomeFragment_to_paymentOptionsFragment)

Try this and let me know if you still face the same issue!

Upvotes: 1

mukesh
mukesh

Reputation: 4140

Action should define in that fragment that contains ViewPager and TabLayout.

I moved the action 'action_currentBillFragment_to_currentBillSummaryFragment' in host fragment of ViewPager and TabLayout.

Upvotes: 5

Related Questions