This question already has answers here:
Android: Where to put activity's onCreate() code in a fragment?
(2 answers)
Closed 8 years ago.
I have started working on fragments.Before starting i wanna clear a doubt whether when to use
onActivitycreate() and onCreate().I did many research but cound not find any relevent answer.Please help.
onActivitycreate() :
onActivitycreate() Called when the fragment's activity has been created and this fragment's view hierarchy instantiated. It can be used to do final initialization once these pieces are in place, such as retrieving views or restoring state. It is also useful for fragments that use setRetainInstance(boolean) to retain their instance, as this callback tells the fragment when it is fully associated with the new activity instance. This is called after onCreateView(LayoutInflater, ViewGroup, Bundle) and before onViewStateRestored(Bundle).
onCreate():
The system calls this when creating the fragment. Within your implementation, you should initialize essential components of the fragment that you want to retain when the fragment is paused or stopped, then resumed.
Read this doc for more details: Fragment Activity Life cycle
onCreate() is sort of like a constructor for the Fragment class, where you normally initialize some variables. In many cases onCreate() is not overriden at all, although it is important to manually define a public empty constructor for every Fragment class.
onCreateView() is the most important method to override when you a create a Fragment (at any rate a Fragment that has a UI). It is analogous to the onCreate() of an Activity: here you inflate the View of the Fragment.
onActivityCreated() is called after the Activity to which the Fragment is attached has been created (i.e. the Activity's onCreate() method has returned without errors) and after the Fragment's View has been inflated.
Related
onActivityCreated seems to mean "This fragment callback is executed just after the activity has been... created... I mean, just after the fragment is correctly attached to the activity. There, you can safely call getActivity, it won't return null, except if the activity is null for some special reason".
However, I've seen that the fragment callback onAttach is called even after OnCreate, it means that the fragment has been attached to the activity, which has been created.
The complete workflow for a fragment (and for a fragment dialog, which is frequently left behind) is: onAttach -> onCreate -> onCreateView -> onActivityCreated. So in each of these 4 methods (perhaps not onAttach I don't know), the activity is normally not null and attached to the fragment.
So my question is: why does the callback onActivityCreated since the activity is, in fact, already created and attached to the fragment 3 callbacks ago???
So basically in onAttach() we get confirmation is that activity is attached to my fragment, I can use getActivity() to fetch things like resources like
getActivity().getResources.getDrawable(R.drawable.abc)
but Suppose if You want to fetch the views inflated in activity's xml like If you want to access
getActivity().findViewById(R.id.Myelement)
You might get null here, so OnActivtyCreated() ensures that activity's view is inflated, You can access activity's views now (Activity's view has been created (onActivityCreated))
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);
}
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.
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
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);
}
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.
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.
onCreateView returns the inflated view. OnViewCreated is called just after onCreateView and get has parameter the inflated view. Its return type is void
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.
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.
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.
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
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.
I don't know when to use onCreate() or onCreateView().
I have used onCreate() and onCreateView() lifecycle methods.
I think onCreate() for Activity and onCreateView() for Fragment. But I am not sure. Can I use onCreate() LifeCycle method in Fragment? I hope somebody can help me!
onCreate is called on initial creation of the fragment. You do your non graphical initializations here. It finishes even before the layout is inflated and the fragment is visible.
onCreateView is called to inflate the layout of the fragment i.e graphical initialization usually takes place here. It is always called some time after the onCreate method.
Activity lifecycle explained - http://developer.android.com/reference/android/app/Activity.html
Fragment lifecycle explained - http://developer.android.com/guide/components/fragments.html#Creating
Detailed lifecycle diagram - https://github.com/xxv/android-lifecycle
From documents :
onCreate
Called when the activity is starting.
This is where most initialization should go: calling setContentView(int) to inflate the activity's UI, using findViewById(int) to programmatically interact with widgets in the UI, calling managedQuery(android.net.Uri, String[], String, String[], String) to retrieve cursors for data being displayed, etc.
You can call finish() from within this function, in which case onDestroy() will be immediately called without any of the rest of the activity lifecycle (onStart(), onResume(), onPause(), etc) executing.
Derived classes must call through to the super class's implementation of this method. If they do not, an exception will be thrown.
Link to documentation of onCreate
onCreateView
Called to have the fragment instantiate its user interface view. This is optional, and non-graphical fragments can return null (which is the default implementation). This will be called between onCreate(Bundle) and onActivityCreated(Bundle).
If you return a View from here, you will later be called in onDestroyView() when the view is being released.
Link to documentation of onCreateView
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);
}
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.
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
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);
}
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.
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.
onCreateView returns the inflated view. OnViewCreated is called just after onCreateView and get has parameter the inflated view. Its return type is void
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.
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.
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.
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
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.
In creation of a fragment, I encountered getActivity() to be null.
So to narrow down the problem, I kept a local copy of activity in onAttach(Activity activity), which by definition is when it is attached to an activity.
However, I logged the activity in onAttach, and it is still null.
I'm only running into this problem in 2.3.6 and below.
Is this a known problem with support package?
The series of methods called to bring a fragment up to resumed state are:
onAttach(Activity) called once the fragment is associated with its activity.
onCreate(Bundle) called to do initial creation of the fragment.
onCreateView(LayoutInflater, ViewGroup, Bundle) creates and returns the view hierarchy associated with the fragment.
onActivityCreated(Bundle) tells the fragment that its activity has completed its own Activity.onCreate().
onViewStateRestored(Bundle) tells the fragment that all of the saved state of its view hierarchy has been restored.
onStart() makes the fragment visible to the user (based on its containing activity being started).
onResume() makes the fragment interacting with the user (based on its containing activity being resumed).
The bold method should be the one where getActivity doesn't return null anymore.
the onAttach method should not be used to call methods of the activity object, It should be used to initialise callback interfaces. An example of these interfaces can be found here.
This problem is because of the support package it means the fragment are from android 3.0 and up that is API level 11 and UP so for sure you will face app crash for android 2.3.6 gingerbird
this.getActivity();