问题
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 :
- open A.
- open B.
- 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.
回答1:
Than behavior is normal, coming from the backstack transaction, as the docs say. The backstack never saves Fragments, it just saves the transaction
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
回答2:
I solved this problem by inheriting (1) all fragments from my custom BaseFragment (2). In this BaseFragment I created a variable: public static boolean removing; (3) and set it to true (4) before calling popBackStackImmediate() and reset it to false after that. (5) In the BaseFragment-childs I check the variable. (6)
Example-Code
Activity-class
BaseFragment.removing = true; //(4)
//pop all fragments
while(getSupportFragmentManager().getBackStackEntryCount() > 0){
fragmentManager.popBackStackImmediate();
}
BaseFragment.removing = false; //(5)
BaseFragment (2)
public class BaseFragment extends Fragment{
public static boolean removing = false; //(3)
}
Fragment-Child
public class fragment extends BaseFragment{ //(1)
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
if(!removing){ // (6)
//your code
}
}
}
来源:https://stackoverflow.com/questions/22278602/popbackstack-causes-calling-oncreateview-of-fragment-again-and-again