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();
}