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