I am using Navigation component. when navigating I want to not create new instance of fragment if it already exists in backstack and pop that already existing in front.
findNavController().navigate(RequestTransferFragmentDirections.actionRequestTransferFragmentToBlankFragment())
looking fowrard to find solution.
thanks.
Answering here because I had the same question. The following is a solution that worked for me. I ended up using the nav controller and popping to a backstack destination if it exists, if it doesn't exist then I navigate to it normally.
This looks like this:
if ( ! nav.popBackStack(R.id.action_profile, false)) {
nav.navigate(R.id.action_profile)
}
nav.popBackStack(R.id.action_profile, false)
will return false if the destination passed in is not in the backstack, otherwise it pops to it and returns true if it is. The boolean is used to pop the destination fragment as well.
From the docs:
/**
* Attempts to pop the controller's back stack back to a specific destination.
*
* @param destinationId The topmost destination to retain
* @param inclusive Whether the given destination should also be popped.
*
* @return true if the stack was popped at least once and the user has been navigated to
* another destination, false otherwise
*/
public boolean popBackStack(@IdRes int destinationId, boolean inclusive) {
boolean popped = popBackStackInternal(destinationId, inclusive);
// Only return true if the pop succeeded and we've dispatched
// the change to a new destination
return popped && dispatchOnDestinationChanged();
}
You can do something like:
bottomNavigation.setupWithNavController(navController)
bottomNavigation.setOnNavigationItemSelectedListener {
if (it.itemId == R.id.navigation_home) {
navController.popBackStack(R.id.navigation_home, false)
true
}
else
NavigationUI.onNavDestinationSelected(it , navController)
}
With the code above whenever the user clicks on the Home (R.id.navigation_home) item in the bottom navigation view, the app will navigate back to the existing instance of the Home destination using the popBackStack().
If the selects another destination in the bottom navigation, the app will navigates to that destination using NavigationUI.onNavDestinationSelected()
I faced the same problem, but the previous solutions didn't work for me unfortunately, in spite of they are supposed to fix the issue. Thanks btw! :)
This worked for me, adapted to your code would be:
findNavController().navigate(
RequestTransferFragmentDirections.actionRequestTransferFragmentToBlankFragment()),
NavOptions.Builder().setLaunchSingleTop(true).build()
)
I saw in the navigate() documentation that we can pass options, so by passing NavOptions.Builder().setLaunchSingleTop(true).build()
will create a single instance of such fragment.
I implemented the request of only one instance of a fragment type in this mode:
in navigation_graph.xml I declared a popUp-action to the fragment-destination
<action
android:id="@+id/home_action"
app:destination="@id/my_dest"
app:popUpTo="@id/my_dest"
app:popUpToInclusive="true" />
<fragment
android:id="@+id/my_dest"
android:name="com.project.android.fragments.MyFragment"
android:label=""
tools:layout="@layout/my_fragment_layout" />
In code I call the action
navController.navigate(R.id.home_action)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With