7

I have simple activity and fragment transaction. What i noticed that on configuration changes oncreateView of Fragment is called twice. Why is this happening?

Activity Code Here :

    @Override
protected void onCreate(Bundle savedInstanceState) {
    System.out.println("Activity created");

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    FragmentManager manager = getSupportFragmentManager();

    BlankFragment fragment = new BlankFragment();

    addFragmentToActivity(manager,
            fragment,
            R.id.root_activity_create
    );
}

public static void addFragmentToActivity (FragmentManager fragmentManager,
                                          Fragment fragment,
                                          int frameId)
                                           {

    FragmentTransaction transaction = fragmentManager.beginTransaction();
    transaction.replace(frameId, fragment);
    transaction.commit();
    }

Fragment Code Here :

public class BlankFragment extends Fragment {


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

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {      
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_blank, container, false);
}

}
Nikolas Bozic
  • 1,071
  • 2
  • 13
  • 20

2 Answers2

11

On first load onCreateView() is called once

But onRotation onCreateView() is called twice

why ?

Because of this transaction.replace(frameId, fragment); Really? Yes,I mean because of fragment .You already have one fragment onFirst load, When you rotate onCreate() will be called once again, so now fragment manager has old fragment ,so it methods will execute(once),and next you are doing transaction replace() which will remove old fragment and replace it with new once and again(onCreateView() will be called for second time). This is repeating for every rotation.

If you use transaction.add(frameId, fragment,UNIQUE_TAG_FOR_EVERY_TRANSACTION) you would know the reason. for every rotatation, no.of onCreateView() calls will increase by 1. that means you are adding fragments while not removing old ones.

But solution is to use old fragments.

in onCreate()of activity

    val fragment = fragmentmanager.findFrgmentByTag("tag")
     val newFragment : BlankFragment
     if(fragment==null){
       newFragment = BlankFragment()
     }else{
       newFragment = fragment as BlankFragment()
     }
     //use newFragment

Hope this solves confusion

Balu Sangem
  • 712
  • 4
  • 16
  • 1
    "for every rotatation, no.of onCreateView() calls will increase by 1" is not true. Look at my answer. Your answer is only half right – DennisVA Feb 15 '18 at 13:14
  • You have to give different tags for every `add` transaction( i mentioned `UNIQUE_TAG_FOR_EVERY_TRANSACTION`) , it will increase.Please try – Balu Sangem Feb 15 '18 at 13:14
  • oh ok indeed that will happen when adding tags, sorry didn't read your answer completely – DennisVA Feb 15 '18 at 13:18
  • This answer is basically the same as mine then. The point is that onCreateView is called twice: once for the fragment that is restored by android, once for the replace of that fragment by a new fragment. your solution is better if a reference to the fragment is needed – DennisVA Feb 15 '18 at 13:21
  • @PrisonMike yes solution is same. But by using `add` transaction,we can know what is causing all these problems. I wanted to explain that. – Balu Sangem Feb 15 '18 at 13:24
  • Just one question, how manager on configuration change has old fragmnet if it is also destryed with conf changes? – Nikolas Bozic Feb 15 '18 at 13:32
  • onDestroy() called to do final cleanup of the fragment's state. so only state is gone, but instance is still alive which hold by FragmentManager(you will add instance to `mAdded:ArrayList`in `FragmentManager` ,when doing transaction ). – Balu Sangem Feb 15 '18 at 13:56
  • You are a legend! – ChaturaM Jun 21 '18 at 01:28
8

Android automatically restores the state of its views after rotation. You don't have to call addFragmentToActivity again after rotation. The fragment will automatically be restored for you!

In your case, it happens twice because: 1. Android restores the fragment, its onCreateView is called 2. You replace the restored fragment with your own fragment, the oncreateview from that fragment is called too

do this:

if (savedInstanceState == null)
{
     addFragmentToActivity(manager, fragment, R.id.test);
}
DennisVA
  • 2,068
  • 1
  • 25
  • 35