Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 913
Fabio Avatar asked Aug 30 '18 16:08

Fabio


3 Answers

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)
like image 134
Marc Alexander Avatar answered Nov 17 '22 15:11

Marc Alexander


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
like image 37
Charles Madere Avatar answered Nov 17 '22 15:11

Charles Madere


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);
like image 2
Fabio Avatar answered Nov 17 '22 15:11

Fabio