Unclude fragment from Backstack using Navigation component

我的未来我决定 提交于 2020-02-25 07:00:47

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!