web-dev-qa-db-fra.com

Destination de navigation inconnue de ce NavController après un résultat d'activité

j'utilise nav controller 1.0.0alpha05 et cela fonctionne très bien, mais je lutte avec cette erreur redoutée lorsque j'exécute une action de navigation après un résultat d'activité.

J'ai une structure d'activité unique/plusieurs fragments, en particulier un fragment avec une liste d'articles et un autre avec le formulaire pour en ajouter un nouveau.

Lorsque j'en ajoute une autre sans aucune image, cela fonctionne et revient à la précédente avec la liste des éléments, mais lorsque je prends des photos, je reçois l'exception pendant la navigation.

Causée par: Java.lang.IllegalArgumentException: la destination de navigation XX est inconnue de ce NavController

Journal des erreurs

Graphique de navigation du fragment de formulaire contenant l'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 de l'appel à l'action avec des arguments sûrs

FormFragmentDirections.ActionFormToList action = new FormFragmentDirections.ActionFormToList(sample.getIdJob());
Navigation.findNavController(getView()).navigate(action);

Merci pour votre temps

6
Fabio

Eh bien, j'ai réussi à trouver une solution ridicule ...

En supposant que vous utilisez un fragment de navigation Host qui s'étend de NavHostFragment , ajoutez-y ce code (Kotlin):

/*
 * 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
 */

Dans les efforts de SEO, la trace de la pile ressemblera à ceci:

Caused by: Java.lang.IllegalArgumentException: navigation destination XX is unknown to this NavController
3
Charles Madere

J'ai trouvé une solution de contournement, mais je ne peux évidemment pas considérer cela comme une solution:

Je pense que lorsque l'état de l'instance de fragment est restauré, la liaison aux actions du nav_graph associé à un tel fragment est en quelque sorte perdue ou quelque chose ... Mais je peux me tromper

Au lieu de pointer vers l'action elle-même, soit via des arguments sûrs ou son identifiant, dans de tels cas, vous pouvez directement utiliser l'identifiant du fragment vers lequel vous souhaitez naviguer.

Dans ce cas, si vous souhaitez transmettre des arguments, vous devez le faire à l'ancienne à travers le bundle.

Bundle args = new Bundle();
args.putString(ID_ARG, arg);
Navigation.findNavController(getView()).navigate(R.id.fragmentId, args);
2
Fabio

Dans mon cas, c'était parce que j'utilisais fragmentManager?.popBackStack() pour revenir en arrière au lieu de naviguer correctement comme ci-dessous:

Navigation.findNavController(activity!!, R.id.fragment_container).navigate(
                Navigation.findNavController(activity!!, R.id.fragment_container).graph.startDestination)
0
Marc Alexander