I have fragment A,B,C,D,E and navigation flow is A->B->C->D->E . So you can say that A is a base fragment from where navigation is starting.
Naviagation flow
Add fragment with Backstack Navigate to Fragment A
A E
-> B (Add B to backstack) -> D (Remove E from backstack)
B D
-> C (Add C to backstack) -> C (Remove D from backstack)
C C
-> D (Add D to backstack) -> B (Remove C from backstack)
D B
-> E (Add E to backstack) -> A (Remove B from backstack)
** Trying to back from A and message pops
(Press once again to exit!)
Add fragment with backstack
public void pushFragmentWithBackState(Fragment DestinationFragment) throws Exception {
try {
Fragment SourceFragment = this;
int viewResourceID = ((ViewGroup) SourceFragment.getView().getParent()).getId();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit);
ft.add(viewResourceID, DestinationFragment);
ft.hide(SourceFragment);
ft.addToBackStack(DestinationFragment.getClass().getName());
ft.commit();
} catch (Exception ex) {
throw ex;
}
}
Back to Fragment A (check Navigate to Fragment A)
In this code I am checking that if there is no back stack entry in fragment manager that mean it we are on Fragment A and I am display message Press again to Exit or simply back from fragment.
@Override
public void onBackPressed() {
// code here to show dialog
//super.onBackPressed(); // optional depending on your needs
if (getSupportFragmentManager().getBackStackEntryCount() >= 1) {
BaseFragment fragment = (BaseFragment) getSupportFragmentManager().getFragments().get(getSupportFragmentManager().getBackStackEntryCount() - 1);
if (fragment != null) {
if (!fragment.onFragmentBackPressed()) {
//super.onBackPressed();
if (back_pressed + 2000 > System.currentTimeMillis()) {
finish();
} else {
Toast.makeText(getBaseContext(), "Press once again to exit!", Toast.LENGTH_SHORT).show();
back_pressed = System.currentTimeMillis();
}
}
} else {
//super.onBackPressed();
if (back_pressed + 2000 > System.currentTimeMillis()) {
finish();
} else {
Toast.makeText(getBaseContext(), "Press once again to exit!", Toast.LENGTH_SHORT).show();
back_pressed = System.currentTimeMillis();
}
}
} else {
if (back_pressed + 2000 > System.currentTimeMillis()) {
finish();
} else {
Toast.makeText(getBaseContext(), "Press once again to exit!", Toast.LENGTH_SHORT).show();
back_pressed = System.currentTimeMillis();
}
}
}
ISSUE
My issue is started if I am trying to navigate from E -> B
and remove all stack exclusively
From Fragment E
poptoBackStackFragment(B.class);
Method
public boolean poptoBackStackFragment(Class SourceFragmentClass) {
getFragmentManager().popBackStack(SourceFragmentClass.getName(),0);
return true;
}
When I am trying to do this it will not clear fragment list(getSupportFragmentManager().getFragments()
) from fragment manager
and with wrong position and when again push in flow for ex. B->C->D fragment list is like :
Find this in Back to fragment A
BaseFragment fragment = (BaseFragment) getSupportFragmentManager().getFragments().get(getSupportFragmentManager().getBackStackEntryCount() - 1);
Example :
- fragment list 1 position having B fragment
- fragment list 4 position having C fragment
- fragment list 3 position having D fragment
- fragment list size is also 5 instead of 2
- there is no sequence in adding fragment in list .Normally it should be position 0,1,2 but instead it is 1,4,3
And because of that my logic of check whether I am on a base fragment is failed and message is coming even I am not on starting fragment (Press again to exit).
Why fragment list is not clear when I am navigate to B and remove all fragment to stack? Am I missing something ? Please help.
Note : I also used FragmentManager.POP_BACK_STACK_INCLUSIVE for clear it from stack but same issue occured.