KaliMa KaliMa - 2 months ago 6
Android Question

Is this the correct way to programmatically invoke a Fragment?

My code:

public class MainActivity extends AppCompatActivity {
private FragmentA fragmentA;

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

if (savedInstanceState == null) {
fragmentA = FragmentA.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_a_container, fragmentA, "FRAGMENT_A");
fragmentTransaction.commit();
}
else {
fragmentA = (FragmentA) getSupportFragmentManager().findFragmentByTag("FRAGMENT_A");
}
}

}


I don't really know what I am doing but this is currently what I do. I define a container for the Fragment and then I use a FragmentTransaction to replace it with a Fragment. The part I am confused about though is the else statement.


  1. Should I be structuring this differently?

  2. I thought configuration changes wiped out Activities and Fragments so why check for the Fragment in some support manager? Does this mean Fragments don't actually get destroyed? At the same time, they DO seem to get destroyed because they appear to reset unless I use
    onSaveInstanceState
    or the
    getArguments()
    approach.



Edit: What's wrong with doing this:

public class MainActivity extends AppCompatActivity {
private FragmentA fragmentA;

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

fragmentA = FragmentA.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_a_container, fragmentA, "FRAGMENT_A");
fragmentTransaction.commit();
}

}

Answer

They do get destroyed and recreated for you on configuration changes by the, in this case, SupportFragmentManager.

To answer your questions:

  1. Should I be structuring this differently?

No, that's exactly how you should create fragments if there is no saved state and retrieve them when there is. See also my answer here;

  1. a) so why check for the Fragment in some support manager?

Because the manager handles the lifecyle of the fragment for you when there is a configuration change.

  1. b) Does this mean Fragments don't actually get destroyed?

No, it does get destroyed. See this diagram for a reference.

Edit to answer some of your questions from the comments:

But any member variables inside that Fragment are completely lost on configuration change unless I save them in that Fragment's onSaveInstanceState, right?

That is correct. Because your fragment is being destroyed, everything not being saved on onSaveInstanceState gets lost.

So then what exactly am I restoring?

You are not restoring anything. You are only retrieving the reference to the fragment that was previously created. You restore your variables on the onRestoreInstanceState() method of your fragment.

What's wrong with doing this (the code from the edit in the question)?

If you do that, you are adding a new fragment instance to the R.id.fragment_a_container container. So the old fragment will get lost together with the state of it you saved on onSaveInstanceState(). It will be a new fragment, with new information in it and the event onRestoreInstanceState() won't be called for it.