How to use NavHostFragment with ViewPager

51 Views Asked by At

So I've already read most of https://developer.android.com/guide/navigation/navigation-multi-module#groovy and fairly understand how to implement nav_graph and stuff. But I kinda have a bit of a complex use-case that I don't have a concrete idea on how to implement.

In my app, I'll be having a structure that looks like this:

Module 1-
    |-Module1_Frag1
        |-Module1_Frag1_SubFrag1
            |-Module1_Frag1_SubSubFrag1
    |...
    |...
Module 2-
    |-Module2_Frag1
        |-Module2_ViewPager1
            |-Module2_Frag1_SubFrag1
                |-Module2_Frag1_SubFrag1_SubFrag1
            |-Module2_Frag1_SubFrag2
                |-Module1_Frag1_SubFrag2_SubFrag1

I'm planning to use DrawerLayout, hence the structure. I know Module 1 is easy to do, but I don't know what to do with Module 2. How should I structure the nav_graph for that? Do I need multiple NavHostFragment for that?

1

There are 1 best solutions below

0
On

I found ideas from the Navigation Drawer Views Activity template. I basically just copied what's in there except for the nav_graph of course. So basically, every screen you have needs to be in a fragment so you can put it inside a fragment as that's how this whole Navigation system works.

As I mentioned above on my question, I was going to put the ViewPager in a Fragment which I didn't completely know was the right move initially was actually what I needed. The only changes that I have to do was transfer some of my code in Activitys to Fragments so I can easily add them on the nav_graph. Then after that was kinda simple. I tried to have multiple nav_graphs then one main nav_graph that included does small ones, but doesn't seem to work. So I just combined them in the end. Here's what my final nav_graph looks like:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_nav_graph"
    app:startDestination="@+id/monitoring_fragment">

    <!--monitoring-->
    <fragment
        android:id="@+id/monitoring_fragment"
        android:name="com.example.app.MonitoringFragment"
        android:label="@string/monitoring"
        tools:layout="@layout/fragment_monitoring">
        <action
            android:id="@+id/showActuatorInfoDetails"
            app:destination="@id/actuatorInfoWithUpdatesFragment" />
        <action
            android:id="@+id/showSensorReadingDetails"
            app:destination="@id/sensorReadingDetailsFragment" />
    </fragment>
    <fragment
        android:id="@+id/actuatorInfoWithUpdatesFragment"
        android:name="com.example.app.ActuatorInfoDetailsFragment"
        android:label="@string/actuator_details"
        tools:layout="@layout/fragment_actuator_info_details">
        <argument
            android:name="actuator_info"
            app:argType="com.example.app.models.api.ActuatorDeviceInfo" />
    </fragment>
    <fragment
        android:id="@+id/sensorReadingDetailsFragment"
        android:name="com.example.app.SensorReadingDetailsFragment"
        android:label="@string/sensor_details"
        tools:layout="@layout/fragment_sensor_reading_details">
        <argument
            android:name="sensor_reading"
            app:argType="com.example.app.models.misc.SensorReading" />
    </fragment>

    <!--user_mgmt-->
    <fragment
        android:id="@+id/login_fragment"
        android:name="com.example.app.fragments.user_mgmt.LoginFragment"
        android:label="@string/login"
        tools:layout="@layout/fragment_login">
        <action
            android:id="@+id/action_loginFragment_to_userManagementFragment"
            app:destination="@id/userManagementFragment" />
    </fragment>
    <fragment
        android:id="@+id/userManagementFragment"
        android:name="com.example.app.fragments.user_mgmt.UserManagementFragment"
        android:label="@string/user_mgmt"
        tools:layout="@layout/fragment_user_management" />
</navigation>

What's kinda weird that I realized in the end, it seems like that I actually need to have the same id for the MenuItem that corresponds to the module and the id for starting "routes" in the nav_graph. Android Studio detects this and I have to accept a Dialog that popped up mentioning the fact. Here's my final menu for the drawer:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:showIn="navigation_view">

    <group android:checkableBehavior="single">
        <item
            android:id="@+id/monitoring_fragment"
            android:title="@string/drawer_menu_monitoring" />
        <item
            android:id="@+id/login_fragment"
            android:title="@string/drawer_menu_user_mgmt" />
    </group>
</menu>

And that's it