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();
Related
I wanted to know how I can get the Fragment which is onloaded on my Acticvity.
The background behind this is, that I want to change the onBackPressed method that it's switching to the right fragments. At the moment when I press "Back" the app closes, because I work alot with fragments.
Use addToBackStack on your fragment transaction. This way when you press the back key the transaction gets rolled back and thus your fragment disappears.
I got a solution for the problem:
Fragment fragment = new Fragment();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = manager.beginTransaction();
fragmentTransaction.add(R.id.Layout,Fragment);
fragmentTransaction.addToBackStack("flow1");
fragmentTransaction.commit();
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
I got a problem. I have master detail view and i replace fragments by fragment manager. It works but after changing some of them i got a memory error. And fragment doesn't have any pictures inside(every replacing fragment have a quite big image).
The question is how to delete those fragment from stack that I'm not using anymore? Preventing memory errors.
how to delete those fragment from stack that I'm not using anymore?
You add to the back state from the FragmentTransaction and remove from the backstack using FragmentManager pop methods:
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction trans = manager.beginTransaction();
trans.remove(myFrag);
trans.commit();
manager.popBackStack();
Hello I am working with sliding menu with fragment.
Indivisual fragment works properly. But suppose user navigates From fragment A->B , now 'B' works perfect and now if user goes from B->A than fragment 'A' is called from onAttach() .
I want such a condition if any fragment is opened , than reopening it should not load whole fragment , it should be resumed just like we handle activity with Intent.FLAG_ACTIVITY_REORDER_TO_FRONT.
Here is my code...
FragmentManager fm = MainActivity.this.getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
Layout1 fragment = new Layout1();
ft.add(R.id.activity_main_content_fragment, fragment,Layout1.class.getName());
ft.addToBackStack(Layout1.class.getName());
ft.commit();
Answer updated:
Reading the documentation, there is a way to pop the back stack based on either the transaction name or the id provided by commit. Using the name may be easier since it shouldn't require keeping track of a number that may change and reinforces the "unique back stack entry" logic.
Since you want only one back stack entry per Fragment, make the back state name the Fragment's class name (via getClass().getName()). Then when replacing a Fragment, use the popBackStackImmediate() method. If it returns true, it means there is an instance of the Fragment in the back stack. If not, actually execute the Fragment replacement logic.
private void replaceFragment (Fragment fragment){
String backStateName = fragment.getClass().getName();
FragmentManager manager = getSupportFragmentManager();
boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0);
if (!fragmentPopped){ //fragment not in back stack, create it.
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.addToBackStack(backStateName);
ft.commit();
}
}
If you return to a fragment from the back stack it does not re-create the fragment but re-uses the same instance and starts with onCreateView() in the fragment lifecycle, see Fragment lifecycle.
So if you want to store state you should use instance variables and not rely on onSaveInstanceState()
Check this link. it will help How to resume Fragment from BackStack if exists
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.