Fabio
Fabio

Reputation: 782

Navigation destination unknown to this NavController after an activity result

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

Upvotes: 12

Views: 16609

Answers (4)

Gk Mohammad Emon
Gk Mohammad Emon

Reputation: 6938

For my case, I resolve the problem by replacing -

 <action
        android:id="@+id/actionFormToList"
        app:destination="@id/idListFragment" />

with

 <action
            android:id="@+id/actionFormToList"
            app:popUpToInclusive="true" /* If true then also remove the destination from stack while popup */
            app:popUpTo="@id/idFormFragment "  /*The fragment where to land again from destination*/
            app:destination="@id/idListFragment" />

Upvotes: 0

Marc Alexander
Marc Alexander

Reputation: 821

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)

Upvotes: 1

Charles Madere
Charles Madere

Reputation: 6832

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

Upvotes: 3

Fabio
Fabio

Reputation: 782

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);

Upvotes: 2

Related Questions