Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FragmentContainerView as NavHostFragment

Seems like using the FragmentContainerView doesn't work right out of the box?

<androidx.fragment.app.FragmentContainerView         class="androidx.navigation.fragment.NavHostFragment"         android:id="@+id/fragment_nav_host"         android:layout_width="match_parent"         android:layout_height="match_parent"         app:defaultNavHost="true"         app:navGraph="@navigation/nav_app" /> 

Here's my code using fragment-ktx:1.2.0-rc01 and I'm just always getting this error:

Caused by: java.lang.IllegalStateException: Activity ...MainActivity@797467d does not have a NavController set on 2131296504 

Just using <fragment> works and AFAIK, it's just supposed to be replaced by FragmentContainerView.

Am I missing something or was anyone able to use FragmentContainerView as a NavHostFragment?

Many thanks!

like image 675
Kurt Acosta Avatar asked Nov 05 '19 02:11

Kurt Acosta


People also ask

What is NavHostFragment?

NavHostFragment provides an area within your layout for self-contained navigation to occur. NavHostFragment is intended to be used as the content area within a layout resource defining your app's chrome around it, e.g.: <androidx.drawerlayout.widget.DrawerLayout.

How do I get NavHostFragment in activity?

Show activity on this post. I solved this by first inflating the view which contains the NavHost, then using the supportFragmentManager to get the navHost Fragment and pass in my default args. Hoping that Google's Android team provides a cleaner solution to this in the future. Show activity on this post.

What is FragmentContainerView?

FragmentContainerView is a customized Layout designed specifically for Fragments. It extends FrameLayout , so it can reliably handle Fragment Transactions, and it also has additional features to coordinate with fragment behavior.


2 Answers

Due to this bug-report: https://issuetracker.google.com/issues/142847973

This is the only way (currently):

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

(Java):

NavHostFragment navHostFragment =     (NavHostFragment) getSupportFragmentManager()         .findFragmentById(R.id.my_nav_host_fragment); NavController navController = navHostFragment.getNavController(); 
like image 66
Ove Stoerholt Avatar answered Sep 21 '22 16:09

Ove Stoerholt


August 2020 update

Here is the solution recommended by the official Android documentation.

Kotlin version:

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

Java version:

NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment); NavController navController = navHostFragment.getNavController(); 

I quote the doc:

When creating the NavHostFragment using FragmentContainerView or if manually adding the NavHostFragment to your activity via a FragmentTransaction, attempting to retrieve the NavController in onCreate() of an Activity via Navigation.findNavController(Activity, @IdRes int) will fail. You should retrieve the NavController directly from the NavHostFragment instead.


The bug-report reported by Ove Stoerholt will not be fixed. You can see here the "Won't Fix (Infeasible)" status.

like image 33
Vince Avatar answered Sep 22 '22 16:09

Vince