Create app with a Fragment containing a Button id=button In
@Override
protected void onStart() {
super.onStart();
getSupportFragmentManager()
.beginTransaction()
.add(R.id.activity_main, new Testfrag())
.commitNow();
View b = findViewById(R.id.button);
}
b is returned as the button and the fragments onCreateView is called before the end of the method.
But in
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm= getSupportFragmentManager();
fm.beginTransaction()
.add(R.id.activity_main, new Testfrag())
.commitNow();
View b = findViewById(R.id.button);
}
b is null and the fragments onCreateView is not called until after the method ends.
This may be a "feature" but there is nothing about it in the documentation.
Why does commit Now behave differently in onCreate - doesn't call onCreateView until later and onStart (or any other event handler) where onCreateView is called synchronously?
I'm honestly surprised the first one works.
If I had to wager, it's the
FragmentManagerdoesn't call the Fragment lifecycle callbacks beyond the point of the Activity's current life cycle. FromonCreate()it will callonAttach()thenonCreate()on the Fragment. At some point betweenonCreateandonStart, the FragmentManager will complete the layout process by callingonCreateView()on every Fragment that has been committed so far. Then it will callonStart()on every fragment when the Activity has started.If you were to commit a Fragment in a later callback, say,
onResume(). The FragmentManager will need to set up the Fragment all the way up to the certain that point, so it's going to go down the lifecycleonAttach(),onCreate(),onCreateView(),onViewCreated(),onStart(), and finallyonResume()all at once. Now the Fragment would be caught up to the rest of the Activity.Generally speaking, there's usually no reason for an Activity to have direct access to a
Fragment'sinternal View elements. The Fragment handles the view events. If necessary, passes the events back up to the Activity. This allows you to alter the Fragment's layout however you want without having to modify the Activity. It also lets you re-use a Fragment in different Activities.