Search code examples
androidtransactionsandroid-listfragment

addToBackStack() duplicating original fragment when pressing back button


Whenever I press the back button of my app the following happens.

Original Phone display: FragA

After clicking a view on FragA Phone display: FragB

After clicking back button Phone display: FragA FragA

I don't know why FragA is recreated but added to the end of a previous FragA when the back button is pressed. Below is my code.

public class ColorListFragment extends ListFragment {
private List<ColorGD> mDrawableList = null;
private ColorAdapter mAdapter = null;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_color_list, container, false);
}

@Override
public void onActivityCreated(Bundle savedInstanceState){

    super.onActivityCreated(savedInstanceState);
        populateList();
        getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            ColorGD viewItem = mDrawableList.get(position);
            float[] hues = {viewItem.getColor(0),viewItem.getColor(1)};

            Bundle args = new Bundle();
            final String hueValues = "hues";
            args.putFloatArray(hueValues,hues);

            SaturationListFragment sLF = new SaturationListFragment();
            sLF.setArguments(args);

            FragmentManager manager = getFragmentManager();
            FragmentTransaction transaction = manager.beginTransaction();
            transaction.replace(R.id.container,sLF);
            transaction.addToBackStack(null);
            transaction.commit();
        }
    });
}

My Main Activity has the following

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    addListFragment();
 }

  public void addListFragment(){
    ColorListFragment cLF = new ColorListFragment();
    FragmentManager manager = getFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();
    transaction.add(R.id.container,cLF);
    transaction.commit();
  }
}

Solution

  • I think I see what's going on here. It's actually impossible for the Fragment to be duplicated with only one view container.

    I suspect that the items in your ListFragment are getting duplicated due to the call to populateList() in onActivityCreated().

    BecauseonActivityCreated() is called every time you click the back button to return to ColorListFragment from SaturationListFragment, it is calling populateList() every time. See documentation here

    In order to fix your issue, just move the call to populateList() to onCreate(), which is only called the first time the ListFragment is initialized:

    public class ColorListFragment extends ListFragment {
      private List<ColorGD> mDrawableList = null;
      private ColorAdapter mAdapter = null;
    
      //add the onCreate() override
      @Override
      public void onCreate(Bundle savedInstance){
          super.onCreate(savedInstance);
          populateList();  //add this here
      }
    
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
          return inflater.inflate(R.layout.fragment_color_list, container, false);
      }
    
      @Override
      public void onActivityCreated(Bundle savedInstanceState){
          super.onActivityCreated(savedInstanceState);
          //populateList();  //remove this
          //..................