I finally solved the issue.

Thanks to @Thracian to pointing me towards navHostManager.getBackStackEntryCount() and the two Listeners that were crucial for debugging.

I solved it now via overriding onBackPressed():

@Override
public void onBackPressed(){
    if (navController.getPreviousBackStackEntry() == null ||
            navController.getCurrentBackStackEntry() == null ||
            navController.getCurrentBackStackEntry()
                    .getDestination().getId() == R.id.nav_dashboardFragment)
        Log.d("MAIN", "back pressed on Dashboard");
    else {
        Log.d("MAIN", "Back pressed. Target: " + navController.getPreviousBackStackEntry().getDestination().getDisplayName());

        Bundle args = new Bundle();
        args.putInt(DashboardFragment.KEY_CANCEL_ANIMATION_ID, 1);
        if (navHostManager.getBackStackEntryCount() > 1)
            navController.navigateUp();
        else
            navController.navigate(R.id.nav_dashboardFragment, args,
                    new NavOptions.Builder().setPopUpTo(R.id.nav_dashboardFragment, true).build());
    }
}

I first check whether I am already on the start destination. If not I check whether getBackStackEntryCount() > 1 to understand whether the next pop back would be the start destination or not. If the next would be the start destination I do not call navigateUp() but instead a direct navigate() with an argument that tells the fragment and most important NavOptions that clear the backstack to not double the startDestination in the back stack (didn’t work without the NavOptions).

In the Fragment I then added:

    if (getArguments() != null && getArguments().get(KEY_CANCEL_ANIMATION_ID) != null) {
        Log.d("DashV", "cancel animation detected");
        motionLayout.setProgress(1);
    }

To cancel the animation in case the argument is found.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top