What does FragmentManager and FragmentTransaction exactly do? - android

I have simple code below
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, mFeedFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
What do these lines of code do?

getFragmentManager()
Return the FragmentManager for interacting with fragments associated
with this activity.
FragmentManager which is used to create transactions for adding, removing or replacing fragments.
fragmentManager.beginTransaction();
Start a series of edit operations on the Fragments associated with
this FragmentManager.
The FragmentTransaction object which will be used.
fragmentTransaction.replace(R.id.fragment_container, mFeedFragment);
Replaces the current fragment with the mFeedFragment on the layout with the id: R.id.fragment_container
fragmentTransaction.addToBackStack(null);
Add this transaction to the back stack. This means that the
transaction will be remembered after it is committed, and will reverse
its operation when later popped off the stack.
Useful for the return button usage so the transaction can be rolled back.
The parameter name:
Is an optional name for this back stack state, or null.
See for information the other question What is the meaning of addToBackStack with null parameter?
The Last statement commits the transaction and executes all commands.
See the google documentation for more help:
http://developer.android.com/reference/android/support/v4/app/FragmentActivity.html
http://developer.android.com/reference/android/app/FragmentManager.html
http://developer.android.com/reference/android/app/FragmentTransaction.html

Android FragmentManager
A FragmentManager manages Fragments in Android, specifically it handles transactions between fragments. A transaction is a way to add, replace, or remove fragments.
Android FragmentTransaction
As said before a FragmentTransaction gives us methods to add, replace, or remove fragments in Android. It gives us an interface for interacting with fragments.
fragmentTransaction.replace(R.id.fragment_container, mFeedFragment);
The method replace(int containerViewId, Fragment fragment) replaces an existing Fragment object from the container containerViewId and adds the the Fragment fragment
fragmentTransaction.addToBackStack(null);
This method, addToBackOfStack(String name), adds this transaction to the back stack, this can be used so that Fragments are remembered and can be used again by the Activity
fragmentTransaction.commit();
The method commit() schedules this transaction, this is not instantaneous; It is scheduled on the main thread to be done when the thread is ready.
Reference

For more readability and simplified transaction You can define simple function or use simple static functions in class
FragmentTransaction :
https://github.com/mahditavakoli1312/FragmentTransaction---mahdi-tavakoli

Related

remove a specific fragment transaction from back stack

I have a fragment manager that has more than one fragment transaction in it. Lets say transactions inside fragment manager is like A->B->C->D->E->F->G. Is there a way that i can pop a specific transaction in back stack ex frag C. I want to pop only one transaction and keep others transactions with same queue.
popBackStack() methods are not covering my case?
Is there anyone who has faced an issue like this?
When committing transactions you need to use tags.
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().add(R.id.mainContainer, fragment, tag).addToBackStack(tag).commit();
Then you'll be able to remove it with this tag;
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.remove(fragmentManager.findFragmentByTag(tag)).commit();

Removing a fragment from the same container

I have 3 fragments added to stage in one and the same container. Two fragments are added with addToBackStack method:
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.container, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
And final one is added without back stack:
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.container, fragment);
fragmentTransaction.commit();
All three co-exist fine because as I understand if a fragment is added using a backstack, then it's not destroyed when another fragment is added.
The last one is added without a backstack, meaning that once I call replace it should be destroyed.
However, this does not happen and when I call
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.container, myNewFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
I can still see that there are 4 fragments total in my R.id.container, which is not that I expect.
How can I make my 3rd fragment disappear when I call replace method when adding 4th fragment?
By calling addToBackStack(), the replace transaction is saved to the
back stack so the user can reverse the transaction and bring back the
previous fragment by pressing the Back button.
So in your case you are replacing the third fragment with the fourth fragment . It means for reversing the transaction they need fragment3 also . So they will not destroy it.

Fragment with MapView is never removed from FragmentManager

I have a Fragment with MapView in it. I add Fragment to container with following code:
Fragment fragment = new MyLocationFragment()
String tag= fragment.getClass().getName();
FragmentTransaction transaction = fm.beginTransaction();
transaction.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left,
R.anim.slide_in_left, R.anim.slide_out_right);
transaction.replace(R.id.container, fragment, tag);
transaction.addToBackStack(null);
transaction.commit();
Now when user presses back, this Fragment is supposed to be removed from FragmentManager. But if execute this code :
Fragment fragment = getSupportFragmentManager().findFragmentByTag(MyLocationFragment.class.getName());
It never returns null, even if I replace other fragments in same container. What can I do to remove Fragment from FragmentManager? Am I doing something wrong here ?
When an activity is destroyed, its FragmentManagersaves out its list of fragments. When the activity is recreated, the new FragmentManager retrieves the list and recreates the listed fragments to make everything as it was before.
[Refer to book "Android Programming The Big Nerd Ranch Guide" P150]
So your should remove fragment from fragmentmanager.
Refer to this Q&A Remove old Fragment from fragment manager
Your question maybe duplicate with thisHow to get a Fragment to remove itself, i.e. its equivalent of finish()?

Is it OK to addToBackStack and replace in a fragment transaction?

Any thoughts on the following code? In my testing I've found the replaced fragment isn't destroyed and the instance is still around when popping the back stack. Just looking to verify that this is a valid way to use fragment transactions.
getSupportFragmentManager().beginTransaction().addToBackStack(null).replace(frame, fragmentB).commit();
My reason for using replace is that it causes the replaced fragment to run it's exit animation.
You can refer to the android designer guide for fragment transaction:
http://developer.android.com/guide/components/fragments.html
Specificly the snippet below:
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
So yes, what you are doing is the correct approach in replacing fragments.

Android FragmentTransaction.addToBackStack confusion

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?
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.
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.
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.
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.

Categories

Resources