VanessaF
VanessaF

Reputation: 793

Error when navigating from a DialogFragment in Android using the navGraph

I want to navigate from a DialogFragment using the navGraph. For that I have onClick methdod that triggers the navigation in the DialogFragment

public void onClick(View view) {
    if (view instanceof ToggleButton) {
        if (binding.tbuttonHighScoreLastWeek.isChecked()) {
            this.pastDaysForDisplayingScores = 7;
        }
        if (binding.tbuttonHighScoreLastMonth.isChecked()) {
            this.pastDaysForDisplayingScores = 30;
        }
        if (binding.tbuttonHighScoreOverall.isChecked()) {
            this.pastDaysForDisplayingScores = 10000;
        }
        viewModel.setPastTimeMillis(pastDaysForDisplayingScores);
    }

    NavController navController = Navigation.findNavController(requireActivity(), R.id.navHostfragment);
    Log.d("NavController", "NavController: " + navController);
    //Repeat the level if the repeat button is pressed
    if (view.getId() == R.id.imageView_RepeatSymbol) {
        navController.navigate(DialogFR_LevelEndDirections.actionDialogFRLevelEndToFRGame());
    }

    if (view.getId() == R.id.imageView_goToMenu) {
        navController.navigate(DialogFR_LevelEndDirections.actionDialogFRLevelEndToFRMenu());
    }

    //Start the next level if the next level button is pressed
    if (view.getId() == R.id.imageView_NextLevelSymbol) {
        navController.navigate(DialogFR_LevelEndDirections.actionDialogFRLevelEndToFRGame());
    }}

Here is the whole class

public class DialogFR_LevelEnd extends DialogFragment implements View.OnClickListener {


    public DialoagFragmentLevelEndingBinding binding;

    private double co2SavingsScore;

    private RecyclerView recyclerView_HighScore;

    private RV_Adapter_Highscore adapter_HighScore;
    private RecyclerView.LayoutManager layoutManager_HighScore;
    private ArrayList<RV_Item_Highscore> arrayList_HighScore;

    private int pastDaysForDisplayingScores = 1000;
    private   int currentLevel;


    //Firebase components
    private ViewModel_DialogFR_LevelEnd viewModel;
    LiveData_FirebaseHighScore liveData;
    DataSnapshot currentDataSnapShotFromFirebase;
    DatabaseReference rootRef_Firebase;

    String FIREBASE_CO_2_SCORE = "co2_score";
    String FIREBASE_DATE = "date";
    String FIREBASE_DATE_IN_MILLISECONDS = "date_in_milliseconds";
    String FIREBASE_LEVEL = "level";
    String FIREBASE_NAME = "name";


    public static DialogFR_LevelEnd newInstance(double co2SavingsScore, double neededCO2SavingScore, int currentLevel) {
        DialogFR_LevelEnd fragment = new DialogFR_LevelEnd();
        Bundle args = new Bundle();
        args.putDouble("co2SavingsScore", co2SavingsScore);
        args.putDouble("neededCO2SavingScore", neededCO2SavingScore);
        args.putInt("currentLevel", currentLevel);
        fragment.setArguments(args);

        /*


        // Set the size of the dialog
        fragment.setCancelable(true); // Can dismiss by tapping outside dialog

        // Get the display metrics of the device
        DisplayMetrics displayMetrics = new DisplayMetrics();
        fragment.getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

        // Calculate x% of the screen width and height
        int screenWidth = (int) (displayMetrics.widthPixels * 0.5);
        int screenHeight = (int) (displayMetrics.heightPixels * 0.5);

        // Set the dialog's width and height
        WindowManager.LayoutParams params = fragment.getDialog().getWindow().getAttributes();
        params.width = screenWidth;
        params.height = screenHeight;
        fragment.getDialog().getWindow().setAttributes(params);

          */




        return fragment;
    }

    public void onViewCreated(Bundle savedInstanceState) {

        // Get the display metrics of the device
        DisplayMetrics displayMetrics = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

        // Calculate x% of the screen width and height
        int screenWidth = (int) (displayMetrics.widthPixels * 0.25);
        int screenHeight = (int) (displayMetrics.heightPixels * 0.25);

        // Set the dialog's width and height
        WindowManager.LayoutParams params = getDialog().getWindow().getAttributes();
        params.width = screenWidth;
        params.height = screenHeight;
        getDialog().getWindow().setAttributes(params);
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        binding = DialoagFragmentLevelEndingBinding.inflate(inflater, container, false);
        double co2SavingsScore = getArguments().getDouble("co2SavingsScore", 0.0);
        double neededCO2SavingsScore = getArguments().getDouble("neededCO2SavingScore", 0.0);
        this.currentLevel = getArguments().getInt("currentLevel", 0);

        binding.textViewLevelFinishedMessageCO2.setText("You needed to save " + neededCO2SavingsScore+ "g of CO2 and you got " + co2SavingsScore + "g");

        //Check if the level was successfull
        if (co2SavingsScore>= neededCO2SavingsScore) {
            //Level passed
            binding.imageViewCloseSymbol.setVisibility(View.INVISIBLE);
        }
        else {
            //Level not passed
            binding.imageViewCheckmark.setVisibility(View.INVISIBLE);
            binding.imageViewRepeatSymbol.setClickable(false);
            binding.imageViewRepeatSymbol.setAlpha(0.5f);
            binding.textViewNextLevel.setAlpha(0.5f);
        }


        // Get the display metrics of the device
        DisplayMetrics displayMetrics = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

        // Calculate x% of the screen width and height
        int screenWidth = (int) (displayMetrics.widthPixels * 0.80);
        int screenHeight = (int) (displayMetrics.heightPixels * 0.80);

        // Set the dialog's width and height
        WindowManager.LayoutParams params = getDialog().getWindow().getAttributes();
        params.width = screenWidth;
        params.height = screenHeight;
        getDialog().getWindow().setAttributes(params);

        //Initialize highScore array list and the RV adapter
        arrayList_HighScore = new ArrayList<RV_Item_Highscore>();
        adapter_HighScore = new RV_Adapter_Highscore(arrayList_HighScore);
        buildRecyclerView();


        //Firebase components
        String FIREBASE_URL = "https://heatinggamehighscores-default-rtdb.europe-west1.firebasedatabase.app/";
        if (FirebaseApp.getApps(getContext()).isEmpty()) {
            FirebaseOptions options = new FirebaseOptions.Builder()
                    .setApplicationId("1:248974012708:android:3f93234ba2066ed41643b1")
                    .setDatabaseUrl(FIREBASE_URL)
                    .build();
            FirebaseApp.initializeApp(getContext(), options);
        }


        rootRef_Firebase = FirebaseDatabase.getInstance(FIREBASE_URL).getReference();
        rootRef_Firebase.keepSynced(true);


        // Obtain a new or prior instance of the ViewModel from the ViewModelProviders utility class.
        viewModel = new ViewModelProvider(this).get(ViewModel_DialogFR_LevelEnd.class);
        viewModel.setFirebaseNodeLevel(currentLevel);
        viewModel.setPastTimeMillis(pastDaysForDisplayingScores);

        liveData = viewModel.getData();
        Log.e("Tag_Dialog", "DialogFragment: ViewModel Get Data Called");
        liveData.observe(this, new Observer<DataSnapshot>() {
            @Override
            public void onChanged(@Nullable DataSnapshot dataSnapshot) {
                // Clear the previous data
                arrayList_HighScore.clear();

                // Check if the snapshot is not null
                if (dataSnapshot != null) {
                    // Convert dataSnapshot to a list for sorting
                    List<DataSnapshot> snapshotList = new ArrayList<>();
                    for (DataSnapshot ds : dataSnapshot.getChildren()) {
                        snapshotList.add(ds);
                    }

                    // Sort the list based on "co2_score" in descending order
                    Collections.sort(snapshotList, new Comparator<DataSnapshot>() {
                        @Override
                        public int compare(DataSnapshot dataSnapshot1, DataSnapshot dataSnapshot2) {
                            Integer co2Score1 = dataSnapshot1.child(FIREBASE_CO_2_SCORE).getValue(Integer.class);
                            Integer co2Score2 = dataSnapshot2.child(FIREBASE_CO_2_SCORE).getValue(Integer.class);
                            return co2Score2.compareTo(co2Score1);
                        }
                    });

                    // Iterate through the sorted list
                    int position = 1; // Initialize position
                    for (DataSnapshot ds : snapshotList) {
                        // Extract data from each snapshot
                        String name = ds.child(FIREBASE_NAME).getValue(String.class);
                        Integer co2Score = ds.child(FIREBASE_CO_2_SCORE).getValue(Integer.class);
                        String date = ds.child(FIREBASE_DATE).getValue(String.class);
                        Integer level = ds.child(FIREBASE_LEVEL).getValue(Integer.class);

                        // Add data to arrayList_HighScore
                        arrayList_HighScore.add(new RV_Item_Highscore(name, co2Score, date, level, position++));
                    }
                }

                // Notify the adapter of the dataset changes
                adapter_HighScore.notifyDataSetChanged();
            }
        });


        //Register the listeners for the clicks
        binding.imageViewRepeatSymbol.setOnClickListener(this);
        binding.imageViewGoToMenu.setOnClickListener(this);
        binding.imageViewNextLevelSymbol.setOnClickListener(this);

        return binding.getRoot();

    }

    public void buildRecyclerView() {
        recyclerView_HighScore = binding.rvHighScoreStatisticsToBeDisplayed;
        recyclerView_HighScore.setHasFixedSize(true);
        layoutManager_HighScore = new LinearLayoutManager(this.getContext());


        recyclerView_HighScore.setLayoutManager(layoutManager_HighScore);
        recyclerView_HighScore.setAdapter(adapter_HighScore);
    }


    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

    }


    @Override
    public void onClick(View view) {
        if (view instanceof ToggleButton) {
            if (binding.tbuttonHighScoreLastWeek.isChecked()) {
                this.pastDaysForDisplayingScores = 7;
            }
            if (binding.tbuttonHighScoreLastMonth.isChecked()) {
                this.pastDaysForDisplayingScores = 30;
            }
            if (binding.tbuttonHighScoreOverall.isChecked()) {
                this.pastDaysForDisplayingScores = 10000;
            }
            viewModel.setPastTimeMillis(pastDaysForDisplayingScores);
        }

        NavController navController = Navigation.findNavController(requireActivity(), R.id.navHostfragment);
        Log.d("NavController", "NavController: " + navController);
        //Repeat the level if the repeat button is pressed
        if (view.getId() == R.id.imageView_RepeatSymbol) {
            navController.navigate(DialogFR_LevelEndDirections.actionDialogFRLevelEndToFRGame());
        }

        if (view.getId() == R.id.imageView_goToMenu) {
            navController.navigate(DialogFR_LevelEndDirections.actionDialogFRLevelEndToFRMenu());
        }

        //Start the next level if the next level button is pressed
        if (view.getId() == R.id.imageView_NextLevelSymbol) {
            navController.navigate(DialogFR_LevelEndDirections.actionDialogFRLevelEndToFRGame());
        }

    }
}

Here is the NavGraph:

<?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"
    android:id="@+id/nav_graph"
    app:startDestination="@id/FR_Menu">

    <fragment
        android:id="@+id/FR_Game"
        android:name="com.example.game.FR_Game"
        android:label="FR_Game" />
    <fragment
        android:id="@+id/FR_Options"
        android:name="com.example.game.FR_Options"
        android:label="FR_Options" />
    <fragment
        android:id="@+id/FR_About"
        android:name="com.example.game.FR_About"
        android:label="FR_About" />
    <fragment
        android:id="@+id/FR_HighScores"
        android:name="com.example.game.FR_HighScores"
        android:label="FR_HighScores" />
    <fragment
        android:id="@+id/FR_Menu"
        android:name="com.example.game.FR_Menu"
        android:label="FR_Menu" >
        <action
            android:id="@+id/action_FR_Menu_to_FR_Game"
            app:destination="@id/FR_Game" />
        <action
            android:id="@+id/action_FR_Menu_to_FR_HighScores"
            app:destination="@id/FR_HighScores" />
        <action
            android:id="@+id/action_FR_Menu_to_FR_InterestingFacts"
            app:destination="@id/FR_InterestingFacts" />
        <action
            android:id="@+id/action_FR_Menu_to_FR_Options"
            app:destination="@id/FR_Options" />
        <action
            android:id="@+id/action_FR_Menu_to_FR_Test"
            />
        <action
            android:id="@+id/action_FR_Menu_to_test"
            app:destination="@id/test" />
        <action
            android:id="@+id/action_FR_Menu_to_test2"
            app:destination="@id/test2" />
        <action
            android:id="@+id/action_FR_Menu_to_FR_RV_Level_Selection_Menu"
            app:destination="@id/FR_RV_Level_Selection_Menu" />
    </fragment>
    <fragment
        android:id="@+id/FR_Tutorial"
        android:name="com.example.game.FR_Tutorial"
        android:label="FR_Tutorial" />
    <fragment
        android:id="@+id/FR_InterestingFacts"
        android:name="com.example.game.FR_InterestingFacts"
        android:label="FR_InterestingFacts" />
    <fragment
        android:id="@+id/test"
        android:name="com.example.game.Test"
        android:label="Test" />
    <fragment
        android:id="@+id/test2"
        android:name="com.example.game.Test2"
        android:label="Test2" />
    <fragment
        android:id="@+id/FR_RV_Level_Selection_Menu"
        android:name="com.example.game.FR_RV_Level_Selection_Menu"
        android:label="FR_RV_Level_Selection_Menu" />
    <dialog
        android:id="@+id/dialogFR_LevelEnd"
        android:name="com.example.game.DialogFR_LevelEnd"
        android:label="DialogFR_LevelEnd" >
        <action
            android:id="@+id/action_dialogFR_LevelEnd_to_FR_Game"
            app:destination="@id/FR_Game" />
        <action
            android:id="@+id/action_dialogFR_LevelEnd_to_FR_Menu"
            app:destination="@id/FR_Menu" />
    </dialog>

</navigation>

Unfortunately, I get an error " Process: com.example.game, PID: 8121 java.lang.IllegalArgumentException: Navigation action/destination com.example.game:id/action_dialogFR_LevelEnd_to_FR_Menu cannot be found from the current destination Destination(com.example.game:id/FR_Game) label=FR_Game class=com.example.game.FR_Game" thown by the line navController.navigate(DialogFR_LevelEndDirections.actionDialogFRLevelEndToFRMenu());. Can you tell me what the problem might me? Because the actionDialogFRLevelEndToFRMenu is defined in the navGraph

Upvotes: 1

Views: 55

Answers (0)

Related Questions