I have an Activity that is holding 5 fragments.
One of those fragments is holding 5 more fragments.
if i add to the fragmentManager a .addToBackStack(null).
the back button returns to the last fragment from the activity and not to the last fragment from the "father" fragment (that is holding 5 more fragments).
Any help please..
EDIT:
ACTIVITY:
fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().
replace(mainContent.getId(), currentFragment)
.addToBackStack(null)
.commit();
FRAGMENT:
fragmentManager = getChildFragmentManager();
fragmentManager.beginTransaction().
replace(mainContent.getId(), currentFragment)
.addToBackStack(null)
.commit();
This is probably the bug mentioned here: https://code.google.com/p/android/issues/detail?id=40323
You can workaround it by handling the 'back' manually. Refer to this thread for a lot of workarounds: Android 4.2: back stack behaviour with nested fragments
I think the issue might be with "the fragmentManager" here. There is more than one FragmentManager.
There is the FragmentManager for the Activity – Activity.getFragmentManager().
And there is the FragmentManager for child Fragments within a Fragment – Fragment.getChildFragmentManager() or Fragment.getFragmentManager().
Let's say you have an activity, a parentFragment and a childFragment. So, instead of activity.getFragmentManager(), I think in your case, you might want either childFragment.getFragmentManager() or parentFragment.getChildFragmentManager().
Note that if you are using the Support package, the names may be different.
Related
I've done some research but I really couldn't find the answer.
I have single activity with side menu, and holder. I have many (non support) fragments, and all of them are using same holder (one at a time).
When user uses menu (it's in main activity), and goes another page, I want to add name of the current fragment to backstack (using .addToBackStack(Fragment1.class.getName())), but I couldn't find how to get current fragment.
I don't want to implement interface etc to keep track of current fragment. There is a super simple way using fragmentManger isn't there?
You can get your current fragment like this:
if (getFragmentManager().getBackStackEntryCount() > 1) {
Fragment f = getFragmentManager().findFragmentById(R.id.content_frame);
if (f instanceof BlankFragment) {
// Do something
}
}
OK,
If you want to get latest entry from backstack(thanks to #AndroidGeek);
fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount()-1);
and, if you want to get currently active fragment (thanks to #Salman500 #AndroidGeek);
Fragment f = getFragmentManager().findFragmentById(R.id.fragment_holder);
you can use this to get fragment id for non support fragment
Fragment fragment = getFragmentManager().findFragmentById(R.id.fragment_id);
if(fragment!=null)
{
getFragmentManager()
.beginTransaction()
.addToBackStack(null)
.commit();
}
You can keep track of fragments in the main activity (with variables) and access them there. Example:
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction= manager.beginTransaction();
MyFragment myFragment = new MyFragment();
myFragment.doSomething();
Adding to the back-stack:
FragmentTransaction fragment = getSupportFragmentManager().beginTransaction();
fragment.addToBackStack(fragment);
fragment.commit();
This is answered here: get currently displayed fragment
Just use addToBackStack() before you commit() the fragment trancsaction. See it here
So your code will look like :
...
fragmentTransaction.replace(R.id.holder, newFragmentToShow, newFragmentTag);
fragmentTransaction.addToBackStack();
fragmentTransaction.commit();
...
EDIT : after OP was edited
You do not need the fragment class to call addToBackStack() as you have mentioned in the OP. The String argument is an optional string just to keep the state for the backstack state. You should see the documentation
It is all internally managed and the current active fragment is automatically added to the backStack, you may call it from where ever you want, it will always use current active fragment.
I have an activity with a fragment A inside of it. The fragment A have nested fragment B inside of it. I'm switching B with C using following code:
getChildFragmentManager()
.beginTransaction()
.setCustomAnimations(R.anim.move_left_in, R.anim.move_left_out,R.anim.move_right_in, R.anim.move_right_out)
.replace(R.id.container, fragmentC)
.addToBackStack("nested")
.commit();
after that Im doing
getChildFragmentManager().popBackStack();
what brings me back to fragment B.
After that I switch fragment A with fragment D using code
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(R.anim.move_up_in, R.anim.move_up_out, R.anim.move_down_in, R.anim.move_down_out)
.replace(R.id.fragment_holder, fragmentD)
.addToBackStack("fragments")
.commit();
and while that animation on A->D transaction is playing, the B plays animation of transaction C->B, and by poping backstack im getting same result, why?
When you switch fragment A with fragment D.
The content within fragment A detach from its parent and then transaction A -> D takes place,
Since you have already set animation to your fragments, delay due to those animation is the reason you,see that left out animation in B first,
then A -> D animation.
Don't use the getChildFragmentManager(),
Use support fragmnetManager means use getSupportFragmentManager why?
Bcz of nested fragment
I hope your problem is solved with this solution. Thank you:)
When I tried to use transitions with fragments using similar code from this article on Medium GitHub. It wouldn't work when I am using the add method() on fragment manager but it would work with replace().
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.addSharedElement(mSharedElement, "transName")
.add(D.id.content_frame, fragment, FRAG_NAME)
.addToBackStack(null)
.commit();
I need to use add() method to keep the fragment below as the user will be navigating back and forth between the first fragment which contains a list of items and the second fragment show detailed info about the item. I don't want to keep loading the fragment with the list again.
Is there a way to get shared element transitions to work when using add() on the fragment manager, than replace().
I have an app that has a single activity where all the screens are displayed as fragments.
So when most of the times I am changing the fragment I add it to the back stack. So the BackStack can get quite big.
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.leftPane, new ReleaseFragmentBuilder(releaseId).build())
.addToBackStack(null)
.commit();
My question is if I want to replace a fragment but do not keep the BackStack anymore(BackStack Reset) , one option is to clear the BackStack by doing a PopBackStack until root (which is super inefficient and have seen other problems) OR to do a fragment replace WITHOUT adding it to the BackStack
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.leftPane, new HomeFragment())
.commit();
So What do you recommend? If I use only the replace , Does it have any memory issues?
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()?