Smith
Smith

Reputation: 1909

Difference between onCreateView and onViewCreated in Fragment

What's the essential difference between these two methods? When I create a TextView, should I use one over the other for performance?

Edit: What's the difference from

onCreateView() {
  root = some view
  View v = new View(some context);
  root.add(v);
  return root;
}


onViewCreated() {
  View v = new View(some context);
  getView().add(v);
}

Upvotes: 182

Views: 151025

Answers (11)

Tristan Elliott
Tristan Elliott

Reputation: 922

  • Ok, so If we are going to talk about onCreateView() and onViewCreated(). It is worth while to talk a little about the fragment lifecycle. The full documentation about the fragment lifecycle can be found HERE, I recommend that you read up on it, as we will only be talking about the states relevant to onCreateView() and onViewCreated().

  • The fragment lifecycle contains 5 states:

  • 1) INITIALIZED

  • 2) CREATED

  • 3) STARTED

  • 4) RESUMED

  • 5) DESTROYED

  • The reason that we need to talk about the fragment lifecycle is because both onCreateView() and onViewCreated() get called during the CREATED state in the lifecycle.

  • So when a fragment is instantiated, it begins in the INITIALIZED state, for example when you see:

CustomFragment frag1 = new CustomFragment() //`INITIALIZED` state
CustomFragment.class                        //`INITIALIZED` state

  • The .class syntax is the class literal syntax and for a brief summary I would recommend reading the blog post HERE

  • For a fragment to transition into other lifecycle states, it must be added to a Fragment Manager.

The Fragment Manager is responsible for determining what state its fragment should be in and then moving them into that state.

Difference between onCreateView() and onViewCreated()

  • Once the fragment has been added to the Fragment Manager, onAttach() is called to attach the fragment to the host activity.

  • Once onAttch() is called the fragment enters the CREATED state. It is in this state that the Android system begins creating the fragment's view. This can be done a few ways, for example the documentation states:

In most cases, you can use the fragment constructors that take a @LayoutId, which automatically inflates the view at the appropriate time. You can also override onCreateView() to programmatically inflate or create your fragment's view

  • If we look at the documentation for onCreateView() we see that:

It is recommended to only inflate the layout in this method and move logic that operates on the returned View to onViewCreated

Conclusion

  • Now combining everything we can come to the conclusion, both onCreateView() and onViewCreated() are called during the CREATED state of a fragment's life cycle. However, onCreateView() is called first and should only be used to inflate the fragment's view. onViewCreated() is called second and all logic pertaining to operations on the inflated view should be in this method.

Upvotes: 8

Emmanuel Conradie
Emmanuel Conradie

Reputation: 435

In the Google Documentation

There is a new solution to declare the xml resource in the Fragment superclass

class ExampleFragment : Fragment(R.layout.example_fragment) { }

Then bind the view in onViewCreate

private lateinit var binding : ExampleFragmentBinding

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    binding = ExampleFragmentBinding.bind(view)
}

In this way you do not need to inflate view in onCreatedView or handle the view in onDestroy

Upvotes: 3

AmeyaB
AmeyaB

Reputation: 1029

The main reason I would use onViewCreated is since it separates any initialization logic from the view hierarchy inflation/creation logic which should go in the onCreateView . All other performance characteristics look the same.

Upvotes: 2

Phantômaxx
Phantômaxx

Reputation: 38098

onCreateView() is the Fragment equivalent of onCreate() for Activities and runs during the View creation.
onViewCreated() runs after the View has been created.

should I use one over the other for performance? NO. There's no evidence of a performance boost.

There is actually an onCreate() method in Fragments too, but it's rarely used (I do never use it, nor find a good use case for it).

I always use onCreateView() in Fragments as a replacement for onCreate().
And I'm happy with that.

Upvotes: 18

Peppe L-G
Peppe L-G

Reputation: 8345

The docs for Fragment.onCreateView() now says:

It is recommended to only inflate the layout in this method and move logic that operates on the returned View to onViewCreated(View, Bundle).

No need for us to understand why; we just need to do as the docs says, but it would be interesting to know why this recommendation exists. My best guess is separation of concern, but IMHO this makes it a little bit more complicated than it has to be.

Upvotes: 18

Zar E Ahmer
Zar E Ahmer

Reputation: 34360

We face some crashes initializing view in onCreateView.

You should inflate your layout in onCreateView but shouldn't initialize other views using findViewById in onCreateView.

Because sometimes view is not properly initialized. So always use findViewById in onViewCreated(when view is fully created) and it also passes the view as parameter.

onViewCreated is a make sure that view is fully created.

onViewCreated android Documentation

Called immediately after onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) has returned, but before any saved state has been restored in to the view. This gives subclasses a chance to initialize themselves once they know their view hierarchy has been completely created. The fragment's view hierarchy is not however attached to its parent at this point.

Upvotes: 141

u3l
u3l

Reputation: 3412

onViewCreated is called immediately after onCreateView (the method you initialize and create all your objects, including your TextView), so it's not a matter of performance.

From the developer site:

onViewCreated(View view, Bundle savedInstanceState)

Called immediately after onCreateView(LayoutInflater, ViewGroup, Bundle) has returned, but before any saved state has been restored in to the view. This gives subclasses a chance to initialize themselves once they know their view hierarchy has been completely created. The fragment's view hierarchy is not however attached to its parent at this point.

Source: Fragment#onViewCreated

Upvotes: 54

Shahriar enayaty
Shahriar enayaty

Reputation: 377

i think the main different between these is when you use kotlin.in onCreateView() every Time you want to access to view in your xml file you should use findViewById but in onViewCreated you can simply access to your view just by calling the id of it.

Upvotes: 2

Salu Khadka
Salu Khadka

Reputation: 49

onCreateView is used in fragment to create layout and inflate view. onViewCreated is used to reference the view created by above method. Lastly it is a good practice to define action listener in onActivityCreated.

Upvotes: 1

Blackbelt
Blackbelt

Reputation: 157437

onCreateView returns the inflated view. OnViewCreated is called just after onCreateView and get has parameter the inflated view. Its return type is void

Upvotes: 14

orangemako
orangemako

Reputation: 954

It's better to do any assignment of subviews to fields in onViewCreated. This is because the framework does an automatic null check for you to ensure that your Fragment's view hierarchy has been created and inflated (if using an XML layout file) properly.

Code snippet from: FragmentManger.java

// This calls onCreateView()
f.mView = f.performCreateView(f.getLayoutInflater(f.mSavedFragmentState), null, f.mSavedFragmentState);

// Null check avoids possible NPEs in onViewCreated
// It's also safe to call getView() during or after onViewCreated()
if (f.mView != null) {
    f.mView.setSaveFromParentEnabled(false);
    if (f.mHidden) f.mView.setVisibility(View.GONE);
    f.onViewCreated(f.mView, f.mSavedFragmentState);
}

Upvotes: 31

Related Questions