Programmatically go back to the previous fragment in the backstack

AndroidAndroid FragmentsBack Stack

Android Problem Overview


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 https://stackoverflow.com/questions/4649508/back-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?

Android Solutions


Solution 1 - Android

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

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

Solution 2 - Android

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();	
	}
}

Solution 3 - Android

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.

Solution 4 - Android

Android Navigation architecture component.

The following code works for me:

findNavController().popBackStack()

Solution 5 - Android

These answers does not work if i don't have addToBackStack() added to my fragment transaction but, you can use:

getActivity().onBackPressed();

from your any fragment to go back one step;

Solution 6 - Android

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();
}

`

Solution 7 - Android

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();

Solution 8 - Android

Kotlin Answer

  1. First, call Fragment Manager.
  2. After, to use onBackPressed() method.

Coding in Android Studio 4.0 with Kotlin:

fragmentManager?.popBackStack()

Solution 9 - Android

Programmatically go back to the previous fragment using following code.

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

Solution 10 - Android

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!

Solution 11 - Android

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();
        }
    });

Solution 12 - Android

Following Kotlin code useful to me

1. Added in Simple Activity class with multiple fragments used

override fun onBackPressed() {
    if (supportFragmentManager.backStackEntryCount > 0) {
        Log.i(TAG, "=============onBackPressed - Popping backstack====")
        supportFragmentManager.popBackStack()
    } else {
        Log.i(TAG, "=============onBackPressed called because nothing on backstack====")
        super.onBackPressed()
    }
}

2. Added in BottomNavigationView Activity class with multiple fragments used

override fun onBackPressed() {

    Log.e(TAG, "=============onBackPressed")
    val navController = findNavController(R.id.nav_host_fragment)
    when (navController.currentDestination!!.id) {
        R.id.navigation_comments, R.id.navigation_my_posts -> {
            menuItemPosition = 0
            navController.navigate(R.id.navigation_home)
            Log.i(TAG, "=============onBackPressed - Popping backstack with First fragment ====")
        }
        else -> {
            Log.i(TAG, "=============onBackPressed called because nothing on backstack====")
            super.onBackPressed()
        }
    }
}

Solution 13 - Android

I came here looking or the same idea, and in the meantime i came up with own, which I believe is not that bad and works if with ViewPager.

So what I did, is to override the onBackPressed method in the parent activity that holds the viewPager, and set it to always go back minus 1 position until it reaches the first fragment, then closes the activity.

@Override
public void onBackPressed() {
    if(viewPager.getCurrentItem()>0){
        viewPager.setCurrentItem(viewPager.getCurrentItem()-1);
    } else {
        super.onBackPressed();
        this.close();
    }
}

private void close(){
    this.finish();
}

This might have a downfalls, like it only goes back one way left each time, so it might not work great if there are tabs and you switch positions with fragments skipped, ( going from 0 to 2, and then pressing back would put you on 1, instead of 0)

For my case tho, with 2 fragments in viewPager without tabs, it does the job nicely.

Solution 14 - Android

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();
            }
        }
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAske B.View Question on Stackoverflow
Solution 1 - AndroidstucklessView Answer on Stackoverflow
Solution 2 - AndroidKyle FalconerView Answer on Stackoverflow
Solution 3 - AndroidJabeerView Answer on Stackoverflow
Solution 4 - AndroidYogesh Nikam PatilView Answer on Stackoverflow
Solution 5 - AndroidBiplob DasView Answer on Stackoverflow
Solution 6 - AndroidAvijit BiswasView Answer on Stackoverflow
Solution 7 - AndroidGiedrius ŠlikasView Answer on Stackoverflow
Solution 8 - AndroidNamelessView Answer on Stackoverflow
Solution 9 - AndroidPiyush MandaliYaView Answer on Stackoverflow
Solution 10 - AndroidSaurabh SinghView Answer on Stackoverflow
Solution 11 - AndroidBaljinder MaanView Answer on Stackoverflow
Solution 12 - AndroidPratik DodiyaView Answer on Stackoverflow
Solution 13 - AndroidGrzesiek EmanView Answer on Stackoverflow
Solution 14 - AndroidadarshView Answer on Stackoverflow