I had an issue in the application I am currently working on it followed the following scenario; Question on stackoverflow
There is an activity, let's call it PaymentFlowActivity. This activity has only 3 fragments; shipping, review and payment fragment and it doesn't have a NavHostFragment.
In the Shipping Fragment, I have more than one state, so I decided to add a NavHostFragment for this fragment to handle back stack for those different states.
so in my fragment layout file, I did the following
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/root_view">
<fragment
android:id="@+id/shipping_host_nav"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/shipping_nav_graph"
app:defaultNavHost="true"/>
<androidx.constraintlayout.widget.ConstraintLayout/>
And when I try to access the nav controller using findNavController() it throws the following exception
java.lang.IllegalStateException:xxxxxxxxxxxxx does not have a NavController set
when I searched for this exception, I didn't find any useful answers to this use case issue.
So, I went through the Navigation component code in the SDK and I found the following: when using the findNavController() with a fragment that isn't NavHostFragment or isn't within NavHostFragment this exception will be thrown.
So we have to find the nav controller by ourselves using the id of the nav host fragment defined in the fragment and the activity as follow
val navController = Navigation.findNavController(activity, R.id.shipping_host_nav)
this will get the navController of your NavHostFragment defined in the fragment layout.
You can use the navController to navigate to the desired destination
navController.navigate(R.id.my_destenation)
To make it easier to get the nav controller, I made an extension function for the fragment class that enables accessing the nav controller using only the id.
Here is a snippet:
fun Fragment.getFragmentNavController(@IdRes id: Int) = activity?.let {
return@let Navigation.findNavController(it, id)
}
Then in your fragment, you can use this method to navigate to the desired destination.
getFragmentNavController(R.id.shipping_host_nav)
.navigate(R.id.action_new_address_to_addresses)
Top comments (1)
please java code:
val navController = Navigation.findNavController(activity, R.id.shipping_host_nav)