问题
I have Fragments X, A, B, and i'm using Navigation architecture component to navigate between them.
Fragments A, B specific, but Fragment X can be any(C,D,...);
Fragments A and B from Bottom Navigation and their "navigations icons" always on the screen, it means user can go to A or B anytime from any Fragment(include A and B):
X -> A -> B
X -> B -> A
A -> B -> X
A -> B -> A
//another ways
My problem about this case:
X -> A -> B -> A -> B -> ?
If user started from X
, reached ?
and begin to go back by "back" button, he goes throw A
,B
several times:
User pressed back:
? -> B -> A -> B -> A -> X
But I want "to exclude" fragments from backstack if they already on it:
? -> A -> B -> X
If user navigate:
X -> A -> B -> A
I want to see:
A -> B -> X
Not:
A -> B -> A -> X
I'm trying to do it with Pop To, but it can return me on one one concrete Fragment only. I need to return on my started X Fragment, not hardcoded. Inclusive and Single top is not about it.
I'm not sure i can do it with basic Navigation component, so i need your advice. If i can't do it, what way should i use? Is there any good practices about it?
UPD:
I'm using global points to navigate between Fragments. It's how my navigation looks like:
The right|bottom chain is X, i can navigate from any of it to to not chanied fragments using bottom navigation. It's Single Activity app, to navigate i'm using just:
//Using global points
findNavController(R.id.host).navigate(R.id.toLibrary)
回答1:
Following Solution uses Fragment Visibility Technique in order to manage Fragments Transaction onBackPressed()
.
In the first step, We assign a tag to each fragment when it's called & invoked in order to be able to recognize which fragments already have been added to Backstack. by code below, we assign a tag to a fragment that is going to be called & transacted.
fragmentManager.beginTransaction()
.replace(R.id.FragmentHolder, Fragment_A OR Fragment_B OR Fragment_ANY, "A or B or ANY")
.addToBackStack(tag).commit();
Remember you must assign a tag to any fragment that you want to be called.
In the second, We are going to Handling public void onBackPressed()
.
You MUST ignore super.onBackPressed();
as becuase, we don't want to defualt onBackPressed function to impact Backstack(as it is) and we are want to handle Backstack ourselves.
Here you go
@Override
public void onBackPressed() {
if(isVisible("A")) { //Go some where else you wanna go }
else if(isVisible("B")){ //Go some where else you wanna go }
else if(isVisible("X or any"){ //Go some where else you wanna go }
else { //Go default page }
}
public boolean isVisible(String tag){
try {
Fragment fragment = fragmentManager.findFragmentByTag(tag);
if (fragment != null && fragment.isVisible())
return true;
else
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
When back button is pressed, We check which fragment is already visible and do redirect user to corresponding Fragment.
For Ex: A - > B
OR A -> X
OR X -> B
I am using this Technique for a big application and all good. Mr.AF grantee
回答2:
In fragmentTransaction instead of using addToBackStack() or add(...) use fragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)
回答3:
maybe this article helps you with your problem: https://developer.android.com/guide/navigation/navigation-getting-started#navigation_and_the_back_stack i think adding popUpToInclusive to your navigationfragment should solve your issue
来源:https://stackoverflow.com/questions/55780523/unclude-fragment-from-backstack-using-navigation-component