i'm using nav controller 1.0.0alpha05 and it is working great, but i'm struggling with this dreaded error when i execute a navigation action after an activity result.
I have a single activity/multiple fragments structure, in particular a fragment with a list of items and another one with the form for adding a new one.
When i add another one without any picture it is working and returning to the previous one with the list of items, but when i take some photos i get the exception during the navigation.
Caused by: java.lang.IllegalArgumentException: navigation destination XX is unknown to this NavController
Error log
Navigation graph of the form fragment containing the action:
<fragment
android:id="@+id/idFormFragment"
android:name="FormFragment"
android:label="FormFragment"
tools:layout="@layout/form_fragment">
<argument
android:name="idClient"
android:defaultValue="-1"
app:argType="integer" />
<argument
android:name="idServer"
app:argType="string" />
<action
android:id="@+id/actionFormToList"
app:destination="@id/idListFragment" />
</fragment>
Code of the action call with safe args
FormFragmentDirections.ActionFormToList action = new FormFragmentDirections.ActionFormToList(sample.getIdJob());
Navigation.findNavController(getView()).navigate(action);
Thanks for your time
Well I've managed to find a ridiculous solution...
Assuming that you are using a host navigation fragment that extends from NavHostFragment
, add this (Kotlin) code to it:
/*
* begin DUMB Navigation Component hack
*
* This fixes an IllegalArgumentException that can sometimes be thrown from within the
* Navigation Architecture Component when you try to navigate after the Fragment has had its
* state restored. It occurs because the navController's currentDestination field is null,
* which stores where we currently are in the navigation graph. Because it's null, the
* Navigation Component can't figure out our current position in relation to where we're
* trying to navigate to, causing the exception to be thrown.
*
* This fix gives the navController a little nudge by gently setting it to where we currently
* are in the navigation graph.
*
* This fix is verified as both working AND necessary as of Navigation Components version
* 1.0.0-alpha07.
*
* There's a tiny bit more information at this thread, but it's pretty limited:
* https://stackoverflow.com/questions/52101617/navigation-destination-unknown-to-this-navcontroller-after-an-activity-result
*/
private var checkCurrentDestination = false
override fun onStart() {
super.onStart()
if (checkCurrentDestination && navController.currentDestination == null) {
navController.navigate(navController.graph.startDestination)
}
checkCurrentDestination = false
}
override fun onStop() {
super.onStop()
checkCurrentDestination = true
}
/*
* end DUMB Navigation Component hack
*/
In the efforts of SEO, the stack trace will look like this:
Caused by: java.lang.IllegalArgumentException: navigation destination XX is unknown to this NavController
I found a workaround but obviously i can't consider it a solution:
I think when the fragment instance state is restored the linking to the actions of the nav_graph associated to such fragment are somehow lost or something... But i can be wrong
Instead of pointing to the action itself, either through safe args or its id, in such cases can be used directly the id of the fragment you want to navigate to.
In this case, if you want to pass arguments, you have to do it the old fashioned way through the bundle.
Bundle args = new Bundle();
args.putString(ID_ARG, arg);
Navigation.findNavController(getView()).navigate(R.id.fragmentId, args);
In my case it was because I was using fragmentManager?.popBackStack()
to navigate back instead of navigating correctly like below:
Navigation.findNavController(activity!!, R.id.fragment_container).navigate(
Navigation.findNavController(activity!!, R.id.fragment_container).graph.startDestination)