Android CommitNow Does Not call onCreateView from onCreate

986 Views Asked by At

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?

1

There are 1 best solutions below

3
On

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. From onCreate() it will call onAttach() then onCreate() on the Fragment. At some point between onCreate and onStart, the FragmentManager will complete the layout process by calling onCreateView() on every Fragment that has been committed so far. Then it will call onStart() 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 lifecycle onAttach(), onCreate(), onCreateView(), onViewCreated(), onStart(), and finally onResume() 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.