Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Navigating out of ViewPager tab using Navigation Components

First, some clarifications. After looking at a lot of other related questions let's start with what this is not:

  • This is not about BottomNavigation
  • This is not about operating the ViewPager using Navigation Components (like this one)

This questions is about how to use Navigation Components, when Viewpager is one of the components.

The situation is having 3 tabs: TabA, TabB, and TabC Also having 2 extra fragments: FragA, FragB

How do I connect them all so that: ViewPagerAdapter is handing TabA, TabB, and TabC AND nav_praph will handle moving from:

  • TabA --> FragA
  • TabB --> FragB
  • TabC --> FragA (not a typo)

Desired UI behavior desired state. Fragment opens above the viewpager First Option: The best I could get working was define the FragHost inside one of the tabs (e.g. TabA) and then navigate to FragA. Problem was the navigation was done INSIDE the tab. Meaning user would still see the tabs on top, and also can still swipe to the other tabs. Not what I wanted. Here is a diagram of what worked, but is not what I wanted (the red symbolizes the hosting fragment) option 1 with nested hosting fragment inside one of the tabs

Second option: move the fragHost to the very top, and have it contain the ViewPager so it takes up full screen. Then in the nagGraph mention

<navigation
    android:id="@+id/nav_graph"
    app:startDestination="@id/tab_a"
    >
    <fragment
      android:id="@+id/tab_a"
      android:name="com.myapp.home.views.TabA"
      android:layout="@layout/tab_a_layout"
      >

    <action
        android:id="@+id/action_tab_a_to_frag_a"
        app:destination="@+id/frag_a"
        />
  </fragment>

  <fragment
      android:id="@+id/frag_a"
      android:name="com.myapp.FragA"
      android:label="details"
      android:layout="@layout/frag_a"
      />

This resulted in an IllegalStateException ... at androidx.fragment.app.FragmentStore.addFragment Some debugging and I saw it was trying to add TabA twice. I assumed both ViewPagerAdapter and Nav Component are using the Fragment manager.

How do I have normal navigation where you can use the tabs, but clicking on one takes you to another full screen experience on top of the tabs?

like image 902
Alon Avatar asked Aug 06 '20 21:08

Alon


1 Answers

Figured out the second option I mentioned is the right way to go. Writing here in case someone else has the same issue.

Make sure your nav_graph is pointing from the containint fragment of the ViewPager and not from the specific fragment the ViewPager is holding. So not from TabA but from ContainerFragmentA which hosts the ViewPager

<navigation
    android:id="@+id/nav_graph"
    app:startDestination="@id/view_pager_hosting_frag"
    >
    <fragment
      android:id="@+id/view_pager_hosting_frag"
      android:name="com.myapp.home.views.ViewPagerHostingFrag"
      android:layout="@layout/view_pager_layout"
      >

    <action
        android:id="@+id/action_tab_a_to_frag_a"
        app:destination="@+id/frag_a"
        />
  </fragment>

  <fragment
      android:id="@+id/frag_a"
      android:name="com.myapp.FragA"
      android:label="details"
      android:layout="@layout/frag_a"
      />

Then you can choose the action you want from any of the tabs to go to the right location

like image 135
Alon Avatar answered Oct 06 '22 23:10

Alon