I have a number of pages/fragments listed in my navigation drawer, the user is likely to switch between these frequently and I want them in the backstack so that they can navigate back, but I only want one instance of each fragment in the backstack so that the user doesn't not have to press back an insane number of times to exit the app. I can't figure out how to effectively 'reorder' the backstack' without pages getting removed.
Currently when I change page I was using this code to change the fragment and make sure it's only in the back stack once
if (mFragMgr == null) {
mFragMgr = getSupportFragmentManager();
}
String backStateName = fragmentDescriptor.name();
boolean fragmentPopped = mFragMgr.popBackStackImmediate(backStateName, 0);
if (!fragmentPopped){
mFragMgr.beginTransaction()
.remove((Fragment) mFragment)
.replace(R.id.content_frame, (Fragment) mFragment)
.addToBackStack(backStateName)
.commit();
}
I use this code in onBackPressed
@Override
public void onBackPressed() {
if (mFragMgr.getBackStackEntryCount() > 0) {
mFragMgr.popBackStackImmediate();
} else {
super.onBackPressed();
}
}
This works but it means it removes pages I don't want removed. Example:
When my user visits 6 pages in the order A > B > C > D > E > C
because I'm doing a remove I expected the following stack:
[E] [C]
[D] [D] [E]
[C] [C] [C] [D]
[B] [B] [B] [B] [B]
[A] -> [A] -> [A] -> [A] -> [A] -> [A]
But what I actually get is the following - it pops everything up to the element that matches the name, this is regardless of whether I include the ".remove((Fragment) mFragment)" or not - (I've already realised now that remove isn't affecting the backstack, so no need to point that out):
[E]
[D] [D]
[C] [C] [C] [C]
[B] [B] [B] [B] [B]
[A] -> [A] -> [A] -> [A] -> [A] -> [A]
If I don't use a name and instead use null when adding to the backstack I get the following:
[C]
[E] [E]
[D] [D] [D]
[C] [C] [C] [C]
[B] [B] [B] [B] [B]
[A] -> [A] -> [A] -> [A] -> [A] -> [A]
How can I get the behaviour I expect? Is it possible at all or am I going to need to record the changes myself and skip the backstack altogether?
This means that the transaction will be remembered after it is committed, and will reverse its operation when later popped off the stack.
setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Fragment fragment = new tasks(); FragmentManager fragmentManager = getActivity(). getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager. beginTransaction(); fragmentTransaction. replace(R.
Can I go from fragment to activity Android? You can add your fragment to the activity's view hierarchy either by defining the fragment in your activity's layout file or by defining a fragment container in your activity's layout file and then programmatically adding the fragment from within your activity.
There is no API to do this, but becuse I was wondering the same thing last week,
I took it as an exercise an implemented it myself.
My method allows you to remove a Fragment
from anywhere in the backstack and this is achieved by using refrection to modify the internal variables that store the backstack information in FragmentManagerImpl and BackStackRecord.
There are few important variables:
mBackStack
- stores the BackStackRecord
s that hold the Fragment
info, the previous ones, animations, etcmActive
- all added Fragment
smAvailBackStackIndices
- stores the indices that can be used by the newly inserted records, i.e. indices of null
values in mActive
Tested with 150+ Fragment
s and couldn't notice any leaks, but only monitored the heap in DDMS
and did not perform any other memory analysis.
So because someting may be broken, explore the code, re-test it, see if anyone provides a better answer, and rethink if you really need to do this in your project.
I uploaded the code as a gist on GitHub, hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With