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.
Related
I have the following code that adds fragments to the same container R.id.container. First I add one fragment, then after user interacts with it, I add another one with the same code
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.container, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
My question when I cell getSupportFragmentManager().getFragments() I can see two fragments. Why doesn't replace actually replace but add?
It keeps the two fragments because
addToBackStack(null);
means the user is able to revert back to the previous state.
If you add fragment1 (using replace), then fragment2, only fragment2 is shown, but if the user press back, the FragmentManager needs to show fragment1, so it keeps a reference to both fragment.
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
My app is using FragmentTransaction to navigate across screens. When i want to go back to the previous fragment using back button, the content of both current and previous fragment merge, and the result is pretty ugly.
For the record, here's my Transaction code :
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.container, new MyFragment());
ft.addToBackStack(null);
ft.commit();
Thanks
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.
I found funny things with fragments. I created activity and added two fragments:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.main, new Fragment1());
ft.add(R.id.main, new Fragment2());
ft.commit();
Then I added button with code:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.main, new Fragment1());
ft.commit();
If I press first time - Fragment1 is destroying, if I press second time - Fragment2 is destroying. Why is it work so? I think that if I'm replacing fragments then container 'main' should be cleaned.
To start, I wouldn't add two fragments to the same container. If you want to use the same container, my recommendation would be to use 2 containers both within a third container
If you need to add two fragments to the same container, you can manually get rid of them by keeping their objects around (or referencing them in some way).
For example this uses the fully qualified FragmentTransaction.add() in order to later reference the fragments
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.main, new Fragment1(), "frag1");
ft.add(R.id.main, new Fragment2(), "frag2");
ft.commit();
// Later on
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
// Manually remove fragments
ft.remove(getSupportFragmentManager().findFragmentByTag("frag1"));
ft.remove(getSupportFragmentManager().findFragmentByTag("frag2"));
ft.add(R.id.main, new Fragment1(), "newFrag1");
ft.commit();
From my understanding, the problem with relying on replace to get rid of multiple fragments inside the same container is that it will replace which ever is "currently showing" not the entire container (although, reading the documentation on FragmentTransaction - it certainly makes it sound like you should be able to do exactly what you are doing).
Take a look at the documentation
"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."
Try to use addToBackStack(null) after the replace:
ft.replace(R.id.main, new Fragment1());
ft.addToBackStack(null)
ft.commit();
suppose fragment f1 and f2
if u replace f2 fragment on f1 then
f1 fragment
onpause
ondestroyview
ondestroy
ondetach
and f2
oncreate
oncreateview
onactivitycreated
onstart
onresume
called
if u add f2 on f1
then
f1
onpause
and f2
oncreate
oncreateview
onactivitycreated
onstart
onresume
are called