Fragments still added to backstack without calling addToBackStack, why?

remove fragment from backstack
android popbackstack to specific fragment
return to previous fragment on back press
previous fragment still visible android
this transaction is already being added to the back stack
fragment replace add to backstack
android popbackstack to first fragment
fragment overlapping in android

I making my fragment changer helper class and i have some issue with it.

I call it FragmentChanger

It has a fragmentContainer, which is a ViewGroup, that holds all the fragments i would like to show.

I have made my own replace(Fragment fragmentToChange, boolean needSaveToBackStack)

function which is:

  • Removing the old fragment fom the fragmentContainer
  • Adding a new fragment to the fragmentContainer
  • Optionally saves to backStack, wether needSaveToBackStack is true or false.

The error is the follwowing:

If i use my replace function with saving to backStack it is works properly, i can use my device's back button to stepping back and back to previsiously added fragments it is works like a charm.

But when i would like to replace a fragment withOUT saving to backStack, there is something wrong in my code because when i stepping back, i can see on the screen the fragment that i NOT added to the backStack, and ALSO i can see an other previsiously added fragment at the same time!

So i can see 2 fragments at the very same time, like this:

This is my code:

//It is my helper class to handle replacing fragments.
public class FragmentChanger {

// fragmentTransaction
FragmentTransaction fragmentTransaction;

// the container for fragments
ViewGroup fragmentContainer;

// activity ofc
Activity act;

// Ctr: adding a default fragment to be the first so we can see it at app
// start
public FragmentChanger(Activity act, ViewGroup container, Fragment startingFragment) {

    this.act = act;
    this.fragmentContainer = container;
    fragmentTransaction = act.getFragmentManager().beginTransaction();
    fragmentTransaction.add(container.getId(), startingFragment, startingFragment.getClass().getSimpleName());
    fragmentTransaction.addToBackStack(startingFragment.getClass().getSimpleName());
    fragmentTransaction.commit();

}

// Replacing a fragment with an other one
public void replace(Fragment fragmentToChange, boolean needSaveToBackStack) {

    fragmentTransaction = act.getFragmentManager().beginTransaction();

    // replacing old fragment to the new one!
    fragmentTransaction.replace(fragmentContainer.getId(), fragmentToChange, fragmentToChange.getClass().getSimpleName());

    // Some null checking, and if the new fragment is NOT equals the current
    // fragment
    if (getCurrentFragment() != null && getCurrentFragment() != fragmentToChange) {

        /*** Important** because something here is wrong ***/

        // only addToBackStack when i want it, when needSaveToBackStack =
        // true!
        if (needSaveToBackStack) {
            fragmentTransaction.addToBackStack(fragmentToChange.getClass().getSimpleName());
        }
    }

    // commiting changes
    fragmentTransaction.commit();

}

// getting current Fragment
private Fragment getCurrentFragment() {

    try {

        FragmentManager fragmentManager = act.getFragmentManager();
        String fragmentTag = fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1).getName();
        Fragment currentFragment = act.getFragmentManager().findFragmentByTag(fragmentTag);
        return currentFragment;

    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return null;
}

// Logging the back stack
public void logBackStack() {

    Log("Logging back stack:", "=============");

    FragmentManager fragmentManager = act.getFragmentManager();
    int stackSize = fragmentManager.getBackStackEntryCount();

    Log("Fragments count on the stack: ", stackSize + "");

    for (int i = 0; i < stackSize; i++) {
        String fragmentTag = fragmentManager.getBackStackEntryAt(i).getName();
        Log("Fragment on the stack: ", fragmentTag);
    }

}

private void Log(String str, String msg) {
    Log.i(str, msg);
}

}

And this is my MainActivity where i test my fragment helper class:

public class MainActivity extends Activity implements OnClickListener {

// My 3 Fragment Classes, could be N other type,
// in this example I only got 3
FragmentA fragmentA;
FragmentB fragmentB;
FragmentC fragmentC;

// Button to add the fragments manually
Button addA, addB, addC;

// This is my activity's container, its a simple viewGroup
// could be anything that can hold fragments
ViewGroup fragmentContainer;

// This is my fragment changer helper class that need some revision by you
// guys
FragmentChanger fragmentChanger;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //defining my adding buttons
    addA = (Button)findViewById(R.id.addAbtn);
    addB = (Button)findViewById(R.id.addBbtn);
    addC = (Button)findViewById(R.id.addCbtn);

    //setting onclicklistenrs
    addA.setOnClickListener(this);
    addB.setOnClickListener(this);
    addC.setOnClickListener(this);

    // defining my main container, this will holds fragments
    fragmentContainer = (ViewGroup) findViewById(R.id.fragmentContainer);

    // defining my fragments, each of them got an Activity (this), a
    // Container (mainContainer), and a Layout ofc.
    fragmentA = new FragmentA(this, fragmentContainer, R.layout.fragment_a_layout);
    fragmentB = new FragmentB(this, fragmentContainer, R.layout.fragment_b_layout);
    fragmentC = new FragmentC(this, fragmentContainer, R.layout.fragment_c_layout);

    // defining my fragment changer with an activity(this), a
    // container(mainContent) and a starting fragment to show!
    fragmentChanger = new FragmentChanger(this, fragmentContainer, fragmentA);

}

@Override
public void onClick(View view) {

    if (view.equals(addA)) {

        //When adding fragmentA, i always want to save it to backstack
        fragmentChanger.replace(fragmentA, true);

    } else if (view.equals(addB)) {

        //I dont want to save to back stack when adding B
        //So if i press back button, i dont want to see fragmentB ever again.
        //(But i do see, this is the error.)
        fragmentChanger.replace(fragmentB, false);
    } else if (view.equals(addC)) {

        //When adding fragmentC, i always want to save it to backstack
        fragmentChanger.replace(fragmentC, true);
    }

    //After any modification on fragments, i log the backstack
    fragmentChanger.logBackStack();

}

}

Ps: I can clearly see that fragmentB is never on the backStack if i logging the stack each time i replace a Fragment with my helper class. Then why is it appears if i push back button?

I greatly appreciate any advice, this is my first attempt with using fragments with my own helper class and i would like to make it greatly usable.


So here what I found wrong with your code:

1) You are mixing together tags of Fragment and BackStackEntry.

String fragmentTag = fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1).getName();

So here you are getting the tag of BackStackEntry (not Fragment), which you adding or not in fragmentTransaction.addToBackStack(). Therefore, you are getting the wrong state and using it as current fragment.

2) It is generally not a good idea to store and reuse fragments like you do in your class fields: FragmentA fragmentA;. It can lead to problems with state and inflation, it is better to create them on every transaction, if you don't want to solve additional puzzles.

Managing the Fragment Back Stack - Bryan Herbst, simple APIs for managing your back stack without headache for most The other quirk I didn't like with this approach was that when calling When adding a Fragment to the back stack, Android developers most The other type of tag is the BackStackRecord's name passed in to addToBackStack(). If you have removed() or replaced() a Fragment and haven’t added it to the backstack, you won’t be able to find it. The other type of tag is the BackStackRecord’s name passed in to


change this line

    fragmentTransaction.add(container.getId(), startingFragment, startingFragment.getClass().getSimpleName());

to

    fragmentTransaction.replace(container.getId(), startingFragment, startingFragment.getClass().getSimpleName());

Simplified Fragment Navigation, using a custom backstack and , Which is why instead, I've integrated Fragments with my own backstack library, the first Activity which is in the background, but its view hierarchy still exists! addToBackStack(null).commit() and navigate only forward and backward, but any Also, commitNow() disallows adding to the FragmentManager's backstack. When launching C from B I would call this static method that adds the transaction to the backstack. But if the user presses the back button, then another popBackStackImmediate is issued . If the user goes from C to another fragment I decided to maintain B in the backstack (but you might want to not do that by moving line 15 within the if


Try to replace the fragment using FragmentTransacion.replace method as shown in link here

And you can refer this example as well. This works for me perfectly.

Fragments backstack working, I am having troules understanding how fragments work in saving and restoring data backstack i guess?) and then calling fragManager.add(container,frag,tag) . additionally, this addTobackstack() method fails when used with the i guess​?) and then calling fragManager.add(container,frag,tag) . No. Seems like this code is useless as I ran the code without the last line .addToBackStack(null).commit() and it ran without any problems. If you want to navigate to previous fragment add it to backstack. So it depends on whether you want to add the fragment to the backstack. How to get that fragment after being added like this ?


Firstly in the constructor to your FragmentChanger class you are adding all the fragments onto your backstack. since you are adding them in order they are getting added as A,B and then C. After adding them to the backstack in that order you are doing more transactions on top of it. While initializing them avoid adding them to the backstack. Only add/remove them whilst doing the actual button click.

There are a lot of replacements going on in your code so i do not know how to really fix this but i can give a general overview of what you should do.

If you want to add a fragment to the backStack then do a.replace(params ).addToBackStack(Tag)

if you dont want to add a particular fragment just skip the addToBackStack(Tag) line completely.

Also your getCurrentFragment() can be changed to

Fragment currentFrag=getFragmentManager().findFragmentById(R.id.fragment_container);

Read this ANSWER here for a better explanation and also this ANSWER

Android Fragments Common Queries & Common Mistakes , Fragment class in Android is used to build dynamic User Interfaces. When to use FragmentTransaction add vs replace ? Fragments are in activity and they are still in memory which does not are not calling addToBackStack and now FragmentC will be on top. Add this transaction to the back stack We use the addToBackStack method of the FragmentTrasaction and we add every fragment to the backstack. In this way when we tap the back button we have the correct behavior. In this post, you learned how to handle Android fragment transaction and how to manage fragments.


Build a flexible UI, Transferring data without draining the battery Add a Fragment to an Activity at Runtime; Replace One Fragment with Another backward through the fragment transactions, you must call addToBackStack() Note: When you remove or replace a fragment and add the transaction to the back stack, the fragment that is​  It's not possible to get into a sub menu without the navigation drawer, so the fragments are basically always removed. In some cases, after I remove and add a fragment again inside an Activity it suddenly overlaps with another (previous) fragment?! But why does the fragment manager suddenly finds previous fragments?


How to resume Fragment from BackStack if exists, I am adding the fragment to an activity like this: Declaring and Every fragment is attached to the activity, and is saved to the back stack without any problem. So when I addToBackStack(backStateName); ft.commit(); // I am using drawer layout mDrawerList. Step 2: When you call the another fragment add this method:. You can use the getName() method of FragmentManager.BackStackEntry which was introduced in API level 14. This method will return a tag which was the one you used when you added the Fragment to the backstack with addTobackStack(tag).


How to avoid Fragments overlapping due to backstack nightmare in , You committed a FragmentTransaction without “addToBackStack” of your fragments (Good boy); you tried to go back just after adding the above B I would call this static method that adds the transaction to the backstack. Check out the blog post: https://goo.gl/nm5yjz If every Activity in your app is part of a task, it makes sense to know what a task is (a stack of activities) and how the default behavior of the