android - Programmatically go back to the previous fragment in the backstack


Translate

Say I have an activity that has fragments added programmatically:

private void animateToFragment(Fragment newFragment, String tag) {
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.replace(R.id.fragment_container, newFragment, tag);
    ft.addToBackStack(null);
    ft.commit();
}

What is the best way to return to the previous fragment that was visible?

I found Trigger back-button functionality on button click in Android but I'm thinking simulating a back key event isn't the right way to go about it (and I can't get it to work either):

dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));

Calling finish() just closes the activity which I'm not interested in.

Is there a better way to go about this?


All Answers
  • Translate

    Look at the getFragmentManager().popBackStack() methods (there are several to choose from)

    http://developer.android.com/reference/android/app/FragmentManager.html#popBackStack()


  • Translate

    To elaborate on the other answers provided, this is my solution (placed in an Activity):

    @Override
    public void onBackPressed(){
        FragmentManager fm = getFragmentManager();
        if (fm.getBackStackEntryCount() > 0) {
            Log.i("MainActivity", "popping backstack");
            fm.popBackStack();
        } else {
            Log.i("MainActivity", "nothing on backstack, calling super");
            super.onBackPressed();  
        }
    }
    

  • Translate

    When we are updating/add the fragments,

    Should Include the .addToBackStack().

    getSupportFragmentManager().beginTransaction()
        .add(detailFragment, "detail") // Add this transaction to the back stack (name is an optional name for this back stack state, or null).
        .addToBackStack(null)
        .commit();
    

    After that if we give the getFragments.popBackStackImmediate() will return true if we add/update the fragments, and move back to the current screen.


  • Translate

    Add those line to your onBackPressed() Method. popBackStackImmediate() method will get you back to the previous fragment if you have any fragment on back stack `

    if(getFragmentManager().getBackStackEntryCount() > 0){
         getFragmentManager().popBackStackImmediate();
    }
    else{
        super.onBackPressed();
    }
    

    `


  • Translate

    This solution works perfectly for bottom bar based fragment navigation when you want to close the app when back pressed in primary fragment.

    On the other hand when you are opening the secondary fragment (fragment in fragment) which is defined as "DetailedPizza" in my code it will return the previous state of primary fragment. Cheers !

    Inside activities on back pressed put this:

    Fragment home = getSupportFragmentManager().findFragmentByTag("DetailedPizza");
    
    if (home instanceof FragmentDetailedPizza && home.isVisible()) {
        if (getFragmentManager().getBackStackEntryCount() != 0) {
            getFragmentManager().popBackStack();
        } else {
            super.onBackPressed();
        }
    } else {
        //Primary fragment
        moveTaskToBack(true);
    }
    

    And launch the other fragment like this:

    Fragment someFragment = new FragmentDetailedPizza();
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    transaction.replace(R.id.container_body, someFragment, "DetailedPizza");
    transaction.addToBackStack("DetailedPizza");
    transaction.commit();
    

  • Translate

    Programmatically go back to the previous fragment using following code.

    if ( getFragmentManager().getBackStackEntryCount() > 0) 
    {
              getFragmentManager().popBackStack();
              return;
    }
    super.onBackPressed();
    

  • Translate

    To make that fragment come again, just add that fragment to backstack which you want to come on back pressed, Eg:

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Fragment fragment = new LoginFragment();
            //replacing the fragment
            if (fragment != null) {
                FragmentTransaction ft = ((FragmentActivity)getContext()).getSupportFragmentManager().beginTransaction();
                ft.replace(R.id.content_frame, fragment);
                ft.addToBackStack("SignupFragment");
                ft.commit();
            }
        }
    });
    

    In the above case, I am opening LoginFragment when Button button is pressed, right now the user is in SignupFragment. So if addToBackStack(TAG) is called, where TAG = "SignupFragment", then when back button is pressed in LoginFragment, we come back to SignUpFragment.

    Happy Coding!


  • Translate

    By adding fragment_tran.addToBackStack(null) on last fragment, I am able to do come back on last fragment.

    adding new fragment:

    view.findViewById(R.id.changepass).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
                transaction.replace(R.id.container, new ChangePassword());
                transaction.addToBackStack(null);
                transaction.commit();
            }
        });
    

  • Translate

    Try below code:

    @Override
        public void onBackPressed() {
            Fragment myFragment = getSupportFragmentManager().findFragmentById(R.id.container);
            if (myFragment != null && myFragment instanceof StepOneFragment) {
                finish();
            } else {
                if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
                    getSupportFragmentManager().popBackStack();
                } else {
                    super.onBackPressed();
                }
            }
        }