1
votes

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:

enter image description here

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)
2
did you get answer ? or i do help you.A Farmanbar
No, i was't. It will be great if you help.KirstenLy
sure.but let me read carefully your question.no worryA Farmanbar

2 Answers

2
votes

the following Solution employs Fragment Visibility Technique in order to Manage Fragments Backstack when onBackPressed().

at first step

We Assign a Tag to each Fragment when it's Called & Invoked to make it possible to Recognize which of Fragments have been Added to Backstack and are predecessors. by below code, we assign a tag to a Fragment that is going to be 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 Transacted.

In the second

We are going to Handling public void onBackPressed().

You MUST ignore super.onBackPressed() Because, we don't Want to defualt onBackPressed Method to Impact Backstack(as it is) while back button is pressed. Moreover, we 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 the user to the Corresponding Predecessor Fragment.

For Ex: A - > B OR A -> X OR X -> B

I am using this Technique for a Released Application and all good.

0
votes

In fragmentTransaction instead of using addToBackStack() or add(...) use fragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)