Vahid
Vahid

Reputation: 1939

NavigationComponent: NavHostFragment inside a fragment

I have this tabbed UI with a navigation component and a BottomNavigationView that handles the tabs. My use case involves one of these tab fragments to have a BottomNavigationView of its own.

I don't think the nested navigation graphs will work for me because I need there to be an inner NavHostFragment and a second BottomNavigationView.

So I'm in the fragment which I wish to host my inner navigation graph. It contains a fragment like so.

<androidx.fragment.app.FragmentContainerView
        android:id="@+id/inner_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:defaultNavHost="true"

I need a way to get the navigation controller for the above fragment.

Normally when you're in an activity you'd call the findFragmentById from the supportFragmentManager with the id you gave to your fragment.

val navHostFragment = supportFragmentManager.findFragmentById(R.id.outer_nav_host) as NavHostFragment

So I tried to call that on the activity object from within my inner fragment

requireActivity().supportFragmentManager.findFragmentById(R.id.inner_host_fragment)

But the findFragmentById returns null.

Upvotes: 5

Views: 4570

Answers (1)

Zain
Zain

Reputation: 40830

Try to get the NavHostFragment from the supportFragmentManager, and then get the navController upon.

val navHostFragment =
        requireActivity().supportFragmentManager.primaryNavigationFragment as NavHostFragment
val navController = navHostFragment.navController

Thanks to @ianhanniballake you need to use the childFragmentManager as your current fragment is a child of a fragment.

So try to use instead:

val navHostFragment =
    childFragmentManager.primaryNavigationFragment as NavHostFragment
val navController = navHostFragment.navController

UPDATE:

throws this java.lang.NullPointerException: null cannot be cast to non-null type androidx.navigation.fragment.NavHostFragment

So, the solution as from comments:

val navHostFragment = childFragmentManager.findFragmentById(R.id.nav_host_fragment) 
                       as NavHostFragment 

And replace nav_host_fragment with the id of the inner NavHostFragment.

Upvotes: 9

Related Questions