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
FragmentManager
doesn'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 betweenonCreate
andonStart
, 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's
internal 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.