popBackStack causes calling oncreateView of fragment again and again

Anshul picture Anshul · Mar 9, 2014 · Viewed 8.5k times · Source

I have 3 fragment A, B,C.I wrote piece of code for replacing them and maintaining backstack:

 public void addFragment(Fragment fragmentToAdd, String fragmentTag) {
        FragmentManager supportFragmentManager = getSupportFragmentManager();
        Fragment activeFragment = getActiveFragment();
        FragmentTransaction fragmentTransaction = supportFragmentManager
                .beginTransaction();
        if (null != activeFragment) {
            fragmentTransaction.hide(activeFragment);
        }
        fragmentTransaction.replace(R.id.layout_child_activity, fragmentToAdd,
                fragmentTag);

       if (supportFragmentManager.getBackStackEntryCount() > 1) {
            supportFragmentManager.popBackStack();
        }
        fragmentTransaction.addToBackStack(fragmentTag);
        fragmentTransaction.commit();
    }

Here in this piece of code

if (supportFragmentManager.getBackStackEntryCount() > 1) {
    supportFragmentManager.popBackStack();
}

I using for pop the latest fragment if stack length is more than 1. Now due to this when length is going greater than 1 than it is calling onCreate view again and again. Like :

  1. open A.
  2. open B.
  3. open C.(In case of open C. onCreateView of A is called. )

Why I am getting such kind of behavior ? When I am removing that italic code than it is not happening.

Answer

user3594530 picture user3594530 · Feb 2, 2016

Than behavior is normal, coming from the backstack transaction, as the docs say. The backstack never saves Fragments, it just saves the transaction

enter image description here

http://developer.android.com/intl/es/guide/components/fragments.html

What I do, I am not sure if, is it the best way but when I want to clear all the transactions I do this

1) INSIDE YOUR ACTIVITY check if is there any transactions in the back stack, and add a flag inside your fragment, in your case is A

       int backStackCount = getSupportFragmentManager().getBackStackEntryCount();

       if(backStackCount > 0) {
           Transactions.MUST_DETACH_FROM_BACKSTACK = true;
           getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
       }

2) Inside your fragment A, get the flag and Remove the fragment onCreateView and return null like this

public class Transactions extends android.support.v4.app.Fragment{

public static boolean MUST_DETACH_FROM_BACKSTACK = false;

public Transactions() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    Log.i("FRAGMENT", "onCreateView "+MUST_DETACH_FROM_BACKSTACK);
    // Inflate the layout for this fragment
    if (MUST_DETACH_FROM_BACKSTACK) {
        MUST_DETACH_FROM_BACKSTACK = false;
        getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
        return null;
    }
    return inflater.inflate(R.layout.fragment_transactions, container, false);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);


    Log.i("FRAGMENT", "onViewCreated");
    if(view != null){

        Log.i("FRAGMENT", "ThreadStarted");
        startThread(view);
    }
}

BUT BE CAREFULL I Get onResume() Called after the

OnCreateView()

even with getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();

So if you have any conde onResume method you should handle it properly