'Multiple/Nested NavHostFragments - Jetpack Navigation

I have two NavHostFragments, one in an activity which is the startDestination and another one in a Fragment. I can't seem to make the Bottom Navigation work in the Fragment with a NavHostFragment.

nav_graph.xml (The first nav_graph) (MainActivity)

nav_graph_main.xml (The second navgraph) (Fragment)

NavigationFragment.java (The one that contains the second NavHostFragment)

public class NavigationFragment extends Fragment {
    FragmentNavigationBinding binding;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_navigation, container, false);
        View view = binding.getRoot();

        NavController navController = Navigation.findNavController(getActivity(), R.id.fragment_navigation_navHostFragment);
        NavigationUI.setupWithNavController(binding.fragmentNavigationBtmNav, navController);

        return view;
    }
}

fragment_navigation.xml

<fragment
        android:id="@+id/fragment_navigation_navHostFragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:defaultNavHost="false"
        app:layout_constraintBottom_toTopOf="@id/fragment_navigation_btmNav"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_graph_main"/>

<com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/fragment_navigation_btmNav"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        app:menu="@menu/bottom_navigation"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"/>

bottom_navigation.xml (Menu)

<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/homeFragment"
        android:icon="@drawable/ic_home"
        android:title="Home" />

    <item
        android:id="@+id/notificationFragment"
        android:icon="@drawable/ic_notification"
        android:title="Notification" />

    <item
        android:id="@+id/waterLevelFragment"
        android:icon="@drawable/ic_water_level"
        android:title="Water Level Map" />

</menu>

The Main Activity has the 1st NavHostFragment. Eventually, the user will be able to reach the NavigationFragment. Once the NavigationFragment has been navigaten into, in the NavigationFragment there is a 2nd NavHostFragment with a BottomNavigationView. I would like that to work. So far, I have only seen examples of BottomNavigation inside an Activity, not Fragment.

The NavigationFragment.java I have right now throws an error when I navigate into it:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.pup.ccis.mmReady, PID: 20253
java.lang.IllegalArgumentException: ID does not reference a View inside this Activity
    at androidx.core.app.ActivityCompat.requireViewById(ActivityCompat.java:371)
    at androidx.navigation.Navigation.findNavController(Navigation.java:58)
    at com.pup.ccis.mmReady.view.main.NavigationFragment.onCreateView(NavigationFragment.java:39)
    at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963)
    at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518)
    at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
    at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189)
    at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2106)
    at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002)
    at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:524)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6077)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)

And I think that this is because it is getting the Activity instead of the Fragment. I don't know any ways to pass the Fragment to findNavController method.

So basically I have something like this:

--MainActivity (contains 1st NavHostFragment for nav_graph.xml)
|--LoginFragment
|--RegisterFragment
|--MainFragment
|--NavigationFragment (contains 2nd NavHostFragment for nav_graph_main.xml)
  |--HomeFragment
  |--NotificationFragment
  |--WaterLevelFragment


Solution 1:[1]

I'm fairly certain I ran into the same issue in the nested NavHostFragment's scenario. It turned out that I seemed to query for nav controller too early in fragments lifecycle. It would find the top level one instead of the one in the current fragment. I solved it by moving setting up the bottom nav with nav controller from onViewCreated to onActivityCreated callback (even though the latter is now deprecated)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 viteqqq