2

My activity is composed of 3 nested Fragments. There is my MainFragment that is displayed by default, ProductFragment that can be called from it, then DetailFragment can be called from ProductFragment.

I can go back and forth between my ProductFragment and DetailFragment. By doing so, the popStackBack method is accumulating similar fragments. Then, if I click on the back button, It will go back through all the Fragments as many time I called them.

What is the proper way to avoid the same Fragment to be kept in the back stack ?

EDIT :

I firstly call my main fragment :

    if (savedInstanceState == null) {
        getFragmentManager()
            .beginTransaction()
            .add(R.id.container, new SearchFragment(), "SEARCH_TAG")
            .commit();
    }

Here is the code that calls the fragments from the activity :

    FragmentManager fm = getFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    ft.setCustomAnimations(R.animator.enter_from_bottom, R.animator.exit_to_top, R.animator.enter_from_bottom, R.animator.exit_to_top);
    ft.replace(R.id.container, new FactFragment(), "FACT_TAG");
    ft.addToBackStack("FACT_TAG");
    ft.commit();

Then, on back click :

@Override
public void onBackPressed() {
    getFragmentManager().popBackStack();
}

I tried to get the tag of my current fragment and execute some specific code related to it but it doesn't work well. I also tried to addToBackStack() only when current Fragment wasn't already added to the backStack but it messed up my fragment view.

keepthepeach
  • 1,621
  • 2
  • 20
  • 27

4 Answers4

4

Use fragment's method isAdded() to evaluate the insertion. For example:

if(!frag.isAdded()){
   //do fragment transaction and add frag
}
waqaslam
  • 67,549
  • 16
  • 165
  • 178
  • Could you please help me here? http://stackoverflow.com/questions/34220607/fragment-is-shown-multiple-times – Jas Dec 11 '15 at 10:02
1

Here is my solution. Maybe dirty but it works. I implemented a method that returns the tag of the fragment that is displayed before clicking the on back button :

public String getActiveFragment() {

    if (getFragmentManager().getBackStackEntryCount() == 0) {
        return null;
    }

    String tag = getFragmentManager()
        .getBackStackEntryAt(getFragmentManager()
        .getBackStackEntryCount() - 1)
        .getName();

    return tag;
}

Then, on my onBackPressed() method :

    // Get current Fragment tag
    String currentFrag = getActiveFragment();

    if(currentFrag.equals("PRODUCT_TAG")) {

        // New transaction to first Fragment
        FragmentManager fm = getFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.setCustomAnimations(R.animator.enter_from_right, R.animator.exit_to_left, R.animator.enter_from_right, R.animator.exit_to_left);
        ft.replace(R.id.container, new SearchFragment(), "MAIN_TAG");
        ft.commit();

    } else {

        // Go to Fragment-1
        getFragmentManager().popBackStack();
    }
keepthepeach
  • 1,621
  • 2
  • 20
  • 27
1

Here is my handy and simple solution to check for duplicate insertion through fragment manager

at first, I check if it is first time intention for adding fragment and then I check if the fragment is presented using fragment manager

  Fragment fragment = getSupportFragmentManager().findFragmentByTag("firstFragment");
                if (fragment == null) {
                    getSupportFragmentManager().beginTransaction().add(R.id.frameLayout, new FirstFragment(), "firstFragment")
                            .addToBackStack(null)
                            .commit();
                }else if(!fragment.isAdded()){
                    getSupportFragmentManager().beginTransaction().add(R.id.frameLayout, new FirstFragment(), "firstFragment")
                            .addToBackStack(null)
                            .commit();
                }
AmirahmadAdibi
  • 358
  • 3
  • 9
0

Here is my solution:

Fragment curFragment = fragmentManager.findFragmentById(R.id.frameLayout);
if(curFragment != null
    && curFragment.getClass().equals(fragment.getClass())) return;

// add the fragment to BackStack here

Xamarin.Android (C#) version:

var curFragment = fragmentManager.FindFragmentById(Resource.Id.frameLayout);    
if (curFragment != null
    && curFragment.GetType().Name == fragment.GetType().Name) return;

// add the fragment to BackStack here
Mehdi Dehghani
  • 10,970
  • 6
  • 59
  • 64