19

I was studying Fragments and got little confused on differentiating FragmentTransaction.replace(id, fragment, tag) and FragmentTransaction.addToBackStack(tag) calls. Lets say that my current fragment is FragmentA and then I loaded FragmentB. I want that in future, when I need to load FragmentA, I don't have to reload it. Just load the old one in old state. I used the following code segment:

public void loadFragment(Fragment fragmentB, String tag) {
    FragmentManager fm = getSupportFragmentManager();
    View fragmentContainer = findViewById(R.id.fragment_container);

    FragmentTransaction ft = fm.beginTransaction();
    ft.replace(fragmentContainer.getId(), fragmentB, tag);

    ft.addToBackStack(tag);

    ft.commit();
}

Now I am confused, where should I add the string tag? In replace() or in addToBackStack() or in both calls? Can you explain the difference between these two tag places?

EnduroDave
  • 1,013
  • 7
  • 18
  • 37
Khawar Raza
  • 15,870
  • 24
  • 70
  • 127

4 Answers4

7

Can you explain the difference between these two tag places?

The documentation for addToBackStack is pretty clear:

An optional name for this back stack state, or null.

While for replace:

Optional tag name for the fragment, to later retrieve the fragment with FragmentManager.findFragmentByTag(String).

So these two parameters are independent, one identifies the back stack, while the other identifies the fragment within Activity's FragmentManager.

Your code seems correct from this point of view, just that I would not search the fragmentContainer view by its id, only to use then its id for replacing the fragment. Make it simpler:

public void loadFragment(Fragment fragmentB, String tag) {
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    ft.replace(R.id.fragment_container, fragmentB, tag);

    ft.addToBackStack(null);

    ft.commit();
}

In case you don't need to identify this back stack later on, pass null for addToBackStack. At least I'm always doing it.

Ghasem
  • 14,455
  • 21
  • 138
  • 171
gunar
  • 14,660
  • 7
  • 56
  • 87
6

In this example you don't need to add tags as identification. Just do:

ft.replace(R.id.fragment_container,fragmentB);
ft.addToBackStack(null);
ft.commit();

The tag as identification is commonly used when you want to add a fragment without a UI.

K Roobroeck
  • 1,378
  • 2
  • 10
  • 13
  • 2
    but in future if I have added multiple fragments to stack and want to load a particular fragment then what? – Khawar Raza Jan 22 '13 at 14:22
  • 5
    Pass a Fragment `TAG` to be able to identify the fragment When adding it to the BackStack: `.addToBackStack(YourFragment.TAG);` So you can check if a Fragment is already in the BackStack using: `getFragmentMangager().findFragmentByTag(YourFragment.TAG);` – Mazen Kasser Jul 08 '13 at 05:37
  • 1
    ft.addToBackStack(null); what is the purpose of this line of code? – Duna Jul 07 '14 at 13:24
  • 2
    http://developer.android.com/guide/components/fragments.html shows us that addToBackStack(null) will ensure that the transaction is also saved to the backstack. Optionally, you can use a name for this backstack state. – K Roobroeck Jul 07 '14 at 13:32
  • 2
    What is "a name for this backstack state"? I mean, what is the purpose of the "backstack state"? – Everett Jul 09 '14 at 06:04
4

Passing null to addtoBackStack(null) means adding the fragment in the Fragment Stack but not adding any TAG which could be further use to identify the particular fragment in a stack before adding again.

    .addToBackStack(null);

But passing TAG to addToBackStack helps in identifying the fragment in Fragment stack by TAG. Like

.addToBackStack(FragmentName.TAG);

Now we can check the fragment before adding it to the Stack :

 getFragmentManager().findFragmentByTag(SettingsFragment.TAG);

This will return null if the Fragment is not already added.

Abhishek kumar
  • 4,347
  • 8
  • 29
  • 44
Narender Gusain
  • 2,220
  • 17
  • 13
2

Param passed to addToBackStack() can be used to retrieve the whole BackStackEntry object, not just a single fragment. In order to set the fragment tag, consider using 3-param versions of add(int, Fragment, String) and replace(int, Fragment, String)

Prior to adding the Fragment you will be able to check if this Fragment is already in the backstack using :

 getFragmentMangager().findFragmentByTag(SettingsFragment.TAG);

This will return null if the Fragment is not already added.

Zar E Ahmer
  • 33,936
  • 20
  • 234
  • 300