Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Remove Fragment and View from BackStack

enter image description here

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.

like image 995
Graham Smith Avatar asked Feb 09 '12 16:02

Graham Smith


People also ask

How do I remove all fragments in the Backstack?

Explanation: MainFragment -> Fragment A -> Fragment B (this is added to backstack) -> Fragment C -> MainFragment (clear backstack ).

How do you delete Backstacks on Android?

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.

What is the use of addToBackStack in Android?

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.


3 Answers

I solved this.. within a line...

getFragmentManager().popBackStack();

or

getSupportFragmentManager().popBackStack()

this works when you are adding fragments and maintaining backstack (not replacing).

like image 74
Bhavesh Hirpara Avatar answered Sep 29 '22 11:09

Bhavesh Hirpara


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..

like image 6
Zar E Ahmer Avatar answered Sep 29 '22 11:09

Zar E Ahmer


Couple of ways to handle this:

  1. 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.

  2. When fragment A is enabled, it can check if fragment C is around by asking the FragmentManager. If it exists then remove it.

like image 1
Nikhil Sohoni Avatar answered Sep 29 '22 13:09

Nikhil Sohoni