web-dev-qa-db-fra.com

L'action est inconnue de ce NavController

Je fournis le transfert de données entre les fragments de deux manières différentes, tout d'abord fonctionne normalement, tandis qu'un type de données sûr provoque un crash d'exécution. J'utilise cela Android docs: https://developer.Android.com/topic/libraries/architecture/navigation/navigation-implementing#Safe-args

Je ne comprends pas comment pourrais-je résoudre le problème. Merci de votre aide

07-13 11:40:07.986 8119-8119/com.flexdecision.ak_Lex.navigationsimple E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.flexdecision.ak_Lex.navigationsimple, PID: 8119
Java.lang.IllegalArgumentException: navigation destination com.flexdecision.ak_Lex.navigationsimple:id/transferAction is unknown to this NavController
    at androidx.navigation.NavController.navigate(NavController.Java:669)
    at androidx.navigation.NavController.navigate(NavController.Java:628)
    at androidx.navigation.NavController.navigate(NavController.Java:690)
    at com.flexdecision.ak_Lex.navigationsimple.InitialFragment.makeTransfer(InitialFragment.Java:58)
    at com.flexdecision.ak_Lex.navigationsimple.InitialFragment.lambda$onViewCreated$0(InitialFragment.Java:47)
    at com.flexdecision.ak_Lex.navigationsimple.-$$Lambda$InitialFragment$shEoLbIe0sVhbTcJ2Al_FvBuU7g.onClick(lambda)
    at Android.view.View.performClick(View.Java:5198)
    at Android.view.View$PerformClick.run(View.Java:21147)
    at Android.os.Handler.handleCallback(Handler.Java:739)
    at Android.os.Handler.dispatchMessage(Handler.Java:95)
    at Android.os.Looper.loop(Looper.Java:148)
    at Android.app.ActivityThread.main(ActivityThread.Java:5417)
    at Java.lang.reflect.Method.invoke(Native Method)
    at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:726)
    at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:616)

Graphique de navigation:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="@+id/nav_graph"
    app:startDestination="@id/initialFragment">

    <fragment
        Android:id="@+id/initialFragment"
        Android:name="com.flexdecision.ak_Lex.navigationsimple.InitialFragment"
        Android:label="fragment_initial"
        tools:layout="@layout/fragment_initial">
        <action
            Android:id="@+id/transferAction"
            app:destination="@+id/nextFragment" />
    </fragment>
    <fragment
        Android:id="@+id/nextFragment"
        Android:name="com.flexdecision.ak_Lex.navigationsimple.NextFragment"
        Android:label="fragment_next"
        tools:layout="@layout/fragment_next" >
        <argument
            Android:name="firstName"
            Android:defaultValue="none"
            app:type="string" />
        <argument
            Android:name="lastName"
            Android:defaultValue="none"
            app:type="string" />
    </fragment>
</navigation>

Disposition de l'activité:

<Android.support.constraint.ConstraintLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    tools:context=".MainActivity">

    <fragment
        Android:id="@+id/nav_Host_fragment"
        Android:name="androidx.navigation.fragment.NavHostFragment"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_graph" />
</Android.support.constraint.ConstraintLayout>

Expéditeur:

import androidx.navigation.Navigation;

public class InitialFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_initial, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Button transactionBtn = view.findViewById(R.id.transaction);
        transactionBtn.setOnClickListener(v -> makeTransfer(v));
    }

    private void makeTransfer(View view) {
        Bundle bundle = new Bundle();
        bundle.putString("name", "Aleksey");
        Navigation.findNavController(view).navigate(R.id.transferAction, bundle);

        //Type safe passing data
        InitialFragmentDirections.TransferAction action = InitialFragmentDirections.transferAction();
        action.setLastName("Petrov");
        Navigation.findNavController(view).navigate(action);
    }
}

Receveur:

public class NextFragment extends Fragment {
    private static final String ARG_PARAM1 = "name";

    private String mParam1;
    private TextView firstName;

    public NextFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            Log.d("Next", "Param: " + mParam1);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_next, container, false);
    }


    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        firstName = view.findViewById(R.id.firstName);
        TextView lastName = view.findViewById(R.id.lastNameTV);
        firstName.setText(mParam1);

        String ln = NextFragmentArgs.fromBundle(getArguments()).getLastName();
        lastName.setText(ln);
    }
}

additionnel:

apply plugin: "androidx.navigation.safeargs"

dependencies {
    def nav_version = "1.0.0-alpha03"

    implementation "Android.Arch.navigation:navigation-fragment:$nav_version"
    implementation "Android.Arch.navigation:navigation-ui:$nav_version"
}
11
Aleksey Kabanov

Vous appelez deux fois à 'Navigation.findNavController (voir) .navigate':

private void makeTransfer(View view) {
    Bundle bundle = new Bundle();
    bundle.putString("name", "Aleksey");
    Navigation.findNavController(view).navigate(R.id.transferAction, bundle);

    //Type safe passing data 
    InitialFragmentDirections.TransferAction action = InitialFragmentDirections.transferAction();
    action.setLastName("Petrov");
    Navigation.findNavController(view).navigate(action);
} 

Première fois avec le bundle et deuxième fois avec des arguments sûrs, mais après le premier appel, votre destination est déjà passée à `` nextFragment '', et lorsque vous appelez le second `` naviguer '', le `` NavController '' recherche l'action `` transferAction '' dans `` nextFragment '' et lève une exception .

13
Alex