FragmentTransaction : replace and addToBackStack not working together?

Viewed 27952

I'm fairly new to Android development and now running in to weird behaviour.

  • I have an empty FrameLayout to be the container of a fragment.
  • If user press a button for the first time, generate new Fragment and put inside container.
  • If user press a button later and there is existing fragment inside container, replace existing one with newly generated one.
  • If user press back button, pop away the fragment inside container.

Here is my code

public void showFragment(View v) {
    FragmentA f = new FragmentA();

    FragmentManager fm = getSupportFragmentManager();
    String tag = f.getFragmentTag(); // instance method of a to get a tag

    FragmentTransaction ft = fm.beginTransaction();
    ft.setCustomAnimations(R.anim.slide_in_top, 0, 0, R.anim.slide_out_top);            
    ft.replace(R.id.container, f, tag);
    ft.addToBackStack(tag);
    ft.commit();
}

@Override
public void onBackPressed() {
    FragmentManager fm = getSupportFragmentManager();
    if (fm.getBackStackEntryCount() > 0) {
        fm.popBackStack();
    } else {
        super.onBackPressed();
    }
}

When user press button for the first time, it behave like what I expected, add new fragment to container. But, the second time user press button while container still contains a fragment, instead of replacing, it add new one on top of existing one. So, 2 fragments inside container, 2 back press to remove all fragment.

I found that if I remove the line

ft.addToBackStack();

And rework the onBackPress() method like following, it works again like I expected (1 fragment in container at a time)

basically, manually remove fragment instead of popFromBackStack method

private FragmentA currentFragment = null; // to hold the reference to exising fragment, if any.

@Override
public void onBackPressed() {
    if (currentFragment != null) {
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.setCustomAnimations(0, R.anim.slide_out_top);
        ft.remove(currentFragment);
        ft.commit();

        currentFragment = null;
    } else {
        super.onBackPressed();
    }
}

So, my question are

  • replace and addToBackStack is not working together?
  • or, did I do something wrong?

Appreciate all comments and suggestions.

2 Answers
Related