Reputation: 793
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