IllegalStateException: Link does not have a NavController set
Solution 1
UPDATED SOLUTION
Actually, Navigation can't find NavController in FrameLayout. So replacing <FrameLayout>
with <fragment>
will make it work.
Add the following inside the <fragment>
tag -
android:name="androidx.navigation.fragment.NavHostFragment"
After doing the changes, the code will look similar to this -
<fragment
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="@navigation/main_navigation"
app:defaultNavHost="true"/>
Solution 2
Officially recommended solution
Currently using the FragmentContainerView is not very friendly, you have to access it from the supportFragmentManager:
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
In my xml my FragmentContainerView looks like this:
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="parent"
app:navGraph="@navigation/nav_graph"
/>
This has been tested with androidx navigation version 2.3.0
I've removed the old answer because it has been clarified by Google devs that it is not the recommended solution anymore. Thanks @Justlearnedit, for posting a comment allowing me to update this issue.
Solution 3
After doing some research I found this Issue also on Google's bugtracker. So here's the official solution in Java:
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager()
.findFragmentById(R.id.nav_host_fragment);
NavController navCo = navHostFragment.getNavController();
and here in Kotlin:
val navHostFragment = supportFragmentManager.findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
Solution 4
The reason is that the fragment view isn't available inside the Activity.onCreate()
method if you're adding it using FragmentContainerView
(or just a FrameLayout
). The proper way to get the NavController
in this case is to find the NavHostFragment
and get the controller from it. See the issue and the explanation.
override fun onCreate(savedInstanceState: Bundle?) {
...
val navHostFragment = supportFragmentManager.findFragmentById(R.id.my_fragment_container_view_id) as NavHostFragment
val navController = navHostFragment.navController
}
Don't use <fragment>
instead of <androidx.fragment.app.FragmentContainerView>
as some other answers suggest. See the comment from the Google team in the issue I mentioned above.
You should always use FragmentContainerView. There are absolutely other fixes around window insets and layout issues that occur when a fragment's root layout is directly within other layouts such as ConstraintLayout, besides the underlying issues with the tag where fragments added via that tag go through lifecycle states entirely differently from the other Fragments added to the FragmentManager. The Lint check is there exactly because you absolutely should switch over to FragmentContainerView in all cases.
There's also an announcement from AndroidDevSummit 2019 which explains why FragmentContainerView
was introduced, and another thread on SO about the difference: <androidx.fragment.app.FragmentContainerView> vs as a view for a NavHost
Solution 5
Just replace <FrameLayout>
With <fragment>
and replace android:name="org.fossasia.openevent.app.core.auth.login.LoginFragment"
with android:name="androidx.navigation.fragment.NavHostFragment"
Masquerade
Updated on December 24, 2021Comments
-
Masquerade over 2 years
I'm using Android Navigation Component for Navigation. I have a LoginFragment which has a button to transition to SignUpFragment. On clicking the button I'm getting this error.
java.lang.IllegalStateException: View android.support.v7.widget.AppCompatButton{49d9bd1 VFED..C.. ...P.... 201,917-782,1061 #7f090172 app:id/signUpLink} does not have a NavController set
Here is my nav_graph.xml
<navigation xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" app:startDestination="@id/loginFragment"> <fragment android:id="@+id/loginFragment" android:name="org.fossasia.openevent.app.core.auth.login.LoginFragment" android:label="login_fragment" tools:layout="@layout/login_fragment"> <action android:id="@+id/action_loginFragment_to_signUpFragment" app:destination="@id/signUpFragment" /> </fragment> </navigation>
Here is the code in LoginFragment for Navigation -
binding.signUpLink.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_loginFragment_to_signUpFragment, null));
Here is extract from activity layout file for NavHostFragment -
<FrameLayout android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" android:name="android.navigation.fragment.NavHostFragment" app:navGraph="@navigation/main_navigation" app:defaultNavHost="true"/>
-
Antek over 5 yearsfor me this unfortunately does not solve the problem - it's the same, actually
-
Peter over 4 yearsThis works fine, but will give a lint warning on the use of the <fragment> tag, stating that it should be replaced with a FragmentContainerView (although doing so will make your app crash).
-
heLL0 over 4 yearsandroid:name="androidx.navigation.fragment.NavHostFragment"
-
Johannes Büttner over 4 years@Peter I was able to solve this by upgrading gradle depedencies of material to
implementation 'com.google.android.material:material:1.2.0-alpha04'
. -
hmac about 4 yearssee here for reason why this is probably good advice: stackoverflow.com/questions/58703451/…
-
Siarhei about 4 yearshad an exception with FragmentContainerView, but works fine with fragment. Also when used FragmentContainerView it give lint warning that app:navGraph not set, but no such warning with fragment
-
Vít Kapitola almost 4 yearsWorks perfectly with Java and FragmentContainerView. (nav_version = "2.3.0")
-
Banana almost 4 yearsIn the issue linked they discuss why you shouldn't use fragment: issuetracker.google.com/issues/142847973#comment15: The Lint check is there exactly because you absolutely should switch over to FragmentContainerView in all cases.
-
Rawa almost 4 years@Justlearnedit Thanks, this was not clear at the point when I posted this answer. Thanks for updating me, I've tested the recommended solution and made sure to update the post to reflect it.
-
Sam Chen over 3 yearsGreat explanation.
-
Big_Chair over 3 years"Method invocation 'getNavController' may produce 'NullPointerException'" so we always have to check for null before as well?
-
Rawa over 3 years@Big_Chair Not sure what method you are referring to. NavHostFragment has a getNavController() function which is annotated with NonNull. Maybe you are using an older version of Navigation?
-
Dr.jacky over 3 yearsCheck this answer and its comments: stackoverflow.com/a/59275182/421467
-
JCrooks over 3 yearsThe recommended solution worked for me on Nav 2.3.3, thank you for pointing that out!
-
Ticherhaz FreePalestine about 3 yearsSomehow it fixed my problem.
-
Anwar Zahid about 3 yearsWow!! After a lot of searching for two days, you buddies solve my problem. Thank you
-
Israel about 3 years@Rawa It is not working for me. I am testing with navigation
2.3.5
. I have seen many posts with this solution, Indeed Android documentation states like you had posted. -
Israel about 3 yearsI have cleaned, build and rebuild but it still not working.
-
jhfdr3s about 3 yearsThis also works when you receive null after minified or ofuscation. Try this.
-
user924 over 2 yearswhat about extension? stackoverflow.com/questions/69190134/…
-
user924 over 2 yearswhat about extension? stackoverflow.com/questions/69190134/…
-
HemangNirmal over 2 yearsthis worked for me stackoverflow.com/questions/59275009/…
-
Kimanthi K. over 2 yearsFantastic way buddy
-
Moustafa EL-Saghier over 2 yearsthis is working perfectly but, removed my toolbar and added one with back button, any idea how to fix this please?
-
user1154390 almost 2 yearsThanks for saving my time , Ref here as well developer.android.com/guide/navigation/…