ains
ains

Reputation: 1446

Replace the top fragment on the back stack

I'm having so much trouble with Android fragments... Suppose my back stack looks like this

[C]
[B]
[A]
---

Pressing the back button would pop Fragment C off, and leaving Fragment B on the top of the stack. Now, how do I swap Fragment C for Fragment D while maintaining the back stack? Note, Fragment B cannot be seen during the operation.

[C] <- [D]               [D]
[B]            ----->    [B]
[A]                      [A]
---                      ---

This way, pressing the back button would pop Fragment D off, and leaving Fragment B on top. Fragment C is completely removed off the stack.

I add each fragments to the stack like so

FragmentTransaction ft = manager.beginTransaction();
ft.replace(id, instance, getTag(instance));
ft.addToBackStack(getTag(instance));
ft.commit();

I thought this could be achieved by doing the same calls without addToBackStack, but it just made Fragment D and Fragment B overlapped.

Upvotes: 14

Views: 4068

Answers (3)

TooLazy
TooLazy

Reputation: 906

A lot of time has passed. I faced the same issue. My solution.

    val topFragment = supportFragmentManager.findFragmentByTag(TAG)
    val transaction = supportFragmentManager.beginTransaction()
    if (topFragment != null) {
            val removeTransaction = supportFragmentManager.beginTransaction()
            supportFragmentManager.popBackStack()
            removeTransaction.remove(currentFragment).commitAllowingStateLoss()
    }
    transaction.add(containerId, newFragment, newFragmentTag)
    transaction.addToBackStack(newFragmentTag)
    transaction.commit()

Upvotes: 0

Tovask
Tovask

Reputation: 477

The fragmentTransaction.replace supposed to replace all the Fragments in the FragmentManager, and then add the new one. According to Google :

This is essentially the same as calling remove(Fragment) for all currently added fragments that were added with the same containerViewId and then add(int, Fragment, String) with the same arguments given here.

But as we see, it isn't always working fine.

(Other useful question about that: FragmentTransaction replace not working )

I use the following code (with the help of fragmentManager.getFragments()):

int top = getSupportFragmentManager().getFragments().size()-1;
while (top > 0 && getSupportFragmentManager().getFragments().get(top) == null) {
    top--;
}
getSupportFragmentManager().beginTransaction()
                 .remove(getSupportFragmentManager().getFragments().get(top))
                 .add(R.id.fragment_container, newfrag).commit();

(I know I didn't use backstack, but I'm a bit confused with that.)

Upvotes: 0

ilomambo
ilomambo

Reputation: 8350

Did you try to pop the back stack before you add fragment D:

FragmentManager fragmentManager = getFragmentManager();
fragmentManager.popBackStack(); // or popBackStackImmediate();
ft.addToBackStack(<fragmentD>);

Upvotes: 4

Related Questions