I realise this question has been asked before however the previous answers have gotten me so far. The scenario is as follows: we have a dashboard fragment (A), which leads a user to a login screen (B). On successful login they go to a listview (c). On backpress I would like to return to A, as the user will not need to see the login screen again. In addition on successful login we store the details in shared preferences and automate the login in B next time, which all works as planned.
I have the following FragmentHelper method:
public static void goToNextFragement(Fragment fragment, int container, boolean addToBackStack, Fragment ctx)
{
// Create new fragment and transaction
FragmentTransaction transaction = ctx.getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(container, fragment);
if(addToBackStack)
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
In the transaction from B to C I set the Boolean addToBackStack as false so that the transaction.addToBackStack(null);
is not called. This again works well but after is where my problem starts.
When the user presses back on C and returns to A I can still see the inflated view of C under the view of A.
Any help would be appreciated. I hope my diagram helps keep this simple.
Explanation: MainFragment -> Fragment A -> Fragment B (this is added to backstack) -> Fragment C -> MainFragment (clear backstack ).
Use finishAffinity() to clear all backstack with existing one. Suppose, Activities A, B and C are in stack, and finishAffinity(); is called in Activity C, - Activity B will be finished / removing from stack. - Activity A will be finished / removing from stack. - Activity C will finished / removing from stack.
addToBackStack. 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.
I solved this.. within a line...
getFragmentManager().popBackStack();
or
getSupportFragmentManager().popBackStack()
this works when you are adding fragments and maintaining backstack (not replacing).
f1 -> f2
Fragment2 f2 = new Fragment2();
this.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.main_content,f2).addToBackStack(null).commit();
nothing out of the ordinary here. Than in fragment f2 this code takes you to fragment f3.
f2 -> f3
Fragment3 f3 = new Fragment3();
getActivity().getSupportFragmentManager().popBackStack();
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.main_content, f3).addToBackStack(null).commit();
I'm not sure by reading docs if this should work, this poping transaction method is said to be asynchronous, and maybe a better way would be to call popBackStackImmediate(). But as far I can tell on my devices it's working flawlessly.
The said alternative would be:
final FragmentActivity activity = getActivity();
activity.getSupportFragmentManager().popBackStackImmediate();
activity.getSupportFragmentManager().beginTransaction().replace(R.id.main_content, f3).addToBackStack(null).commit();
Here there will actually be brief going back to f1 beofre moving on to f3, so a slight glitch there.
This is actually all you have to do and this answer can also help you alot..
Couple of ways to handle this:
I had a similar flow in my app and the way I solved it was by replacing the login fragment with a AlertDialog that's fired from the main activity. So in your case, fragment A shows up on screen and if the main activity thinks it needs to show the login dialog, it shows the AlertDialog. This worked for me.
When fragment A is enabled, it can check if fragment C is around by asking the FragmentManager. If it exists then remove it.
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