Android Fragment Oncreateview VS. Onactivitycreated

Android Fragment onCreateView vs. onActivityCreated

If your view is static, then moving any code to the onActivityCreated method is not necessary. But when you - for instance, fill some lists from the adapter, then you should do it in the onActivityCreated method as well as restoring the view state when setRetainInstance used to do so.

Also accessing the view hierarchy of the parent activity must be done in the onActivityCreated, not sooner.

Difference and uses of onCreate(), onCreateView() and onActivityCreated() in fragments

UPDATE:

onActivityCreated() is deprecated from API Level 28.


onCreate():

The onCreate() method in a Fragment is called after the Activity's onAttachFragment() but before that Fragment's onCreateView().

In this method, you can assign variables, get Intent extras, and anything else that doesn't involve the View hierarchy (i.e. non-graphical initialisations). This is because this method can be called when the Activity's onCreate() is not finished, and so trying to access the View hierarchy here may result in a crash.

onCreateView():

After the onCreate() is called (in the Fragment), the Fragment's onCreateView() is called. You can assign your View variables and do any graphical initialisations. You are expected to return a View from this method, and this is the main UI view, but if your Fragment does not use any layouts or graphics, you can return null (happens by default if you don't override).

onActivityCreated():

As the name states, this is called after the Activity's onCreate() has completed. It is called after onCreateView(), and is mainly used for final initialisations (for example, modifying UI elements). This is deprecated from API level 28.


To sum up...

... they are all called in the Fragment but are called at different times.

The onCreate() is called first, for doing any non-graphical initialisations. Next, you can assign and declare any View variables you want to use in onCreateView(). Afterwards, use onActivityCreated() to do any final initialisations you want to do once everything has completed.


If you want to view the official Android documentation, it can be found here:

  • onCreate()
  • onCreateView()
  • onActivityCreated()_

There are also some slightly different, but less developed questions/answers here on Stack Overflow:

  • onCreate() vs onCreateView()
  • onCreateView() vs onActivityCreated()

Is onActivityCreated() called after onViewCreated() in a Fragment?

After some further research I think I found the answer.

onActivityCreated added in version 22.1.0 void onActivityCreated
(Bundle savedInstanceState)

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).

Based on the documentation:

..fragment's view hierarchy instantiated. It can be used to do final
initialization once these pieces are in place..

The view hierarchy should be fully instantiated and therefore onActivityCreated will be called after the completion of onViewCreated

UPDATE

Info: onActivityCreated is now deprecated

use onViewCreated(View, Bundle) for code touching the Fragment's view
and onCreate(Bundle) for other initialization. To get a callback
specifically when a Fragment activity's Activity.onCreate(Bundle) is
called, register a androidx.lifecycle.LifecycleObserver on the
Activity's Lifecycle in onAttach(Context), removing it when it
receives the Lifecycle.State.CREATED callback.

Setup view inside onCreateView vs onActivityCreated

You can really use whatever you want, as long as it works.

However, I believe onViewCreated() is technically the "official" or recommended way to modify and reference your View after it's been created.

Fragment Recyclerview onCreateView, onViewCreated or onActivityCreated?

onCreateView() will be the best choice since you're using Fragment. The difference is onCreateView() is the Fragment equivalent of onCreate() for Activities and runs during the View creation but onViewCreated() runs after the View has been created.

And onActivityCreated() calls after onCreate() method of the Activity completes as you can see in here: https://stackoverflow.com/a/44582434/4409113

Fragment onCreateView and onActivityCreated called twice

Ok, Here's what I found out.

What I didn't understand is that all fragments that are attached to an activity when a config change happens (phone rotates) are recreated and added back to the activity. (which makes sense)

What was happening in the TabListener constructor was the tab was detached if it was found and attached to the activity. See below:

mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag);
if (mFragment != null && !mFragment.isDetached()) {
Log.d(TAG, "constructor: detaching fragment " + mTag);
FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction();
ft.detach(mFragment);
ft.commit();
}

Later in the activity onCreate the previously selected tab was selected from the saved instance state. See below:

if (savedInstanceState != null) {
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
Log.d(TAG, "FragmentTabs.onCreate tab: " + savedInstanceState.getInt("tab"));
Log.d(TAG, "FragmentTabs.onCreate number: " + savedInstanceState.getInt("number"));
}

When the tab was selected it would be reattached in the onTabSelected callback.

public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName(), mArgs);
Log.d(TAG, "onTabSelected adding fragment " + mTag);
ft.add(android.R.id.content, mFragment, mTag);
} else {
Log.d(TAG, "onTabSelected attaching fragment " + mTag);
ft.attach(mFragment);
}
}

The fragment being attached is the second call to the onCreateView and onActivityCreated methods. (The first being when the system is recreating the acitivity and all attached fragments) The first time the onSavedInstanceState Bundle would have saved data but not the second time.

The solution is to not detach the fragment in the TabListener constructor, just leave it attached. (You still need to find it in the FragmentManager by it's tag) Also, in the onTabSelected method I check to see if the fragment is detached before I attach it. Something like this:

public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName(), mArgs);
Log.d(TAG, "onTabSelected adding fragment " + mTag);
ft.add(android.R.id.content, mFragment, mTag);
} else {

if(mFragment.isDetached()) {
Log.d(TAG, "onTabSelected attaching fragment " + mTag);
ft.attach(mFragment);
} else {
Log.d(TAG, "onTabSelected fragment already attached " + mTag);
}
}
}

onActivityCreated is deprecated, how to properly use LifecycleObserver?

All I needed was onActivityCreated(...), hence I did implement an observer that:

  • Automatically removes itself (using .removeObserver(...)).
  • Then calls passed callback (update()).

I did it in next way:

class MyActivityObserver(
private val update: () -> Unit
) : DefaultLifecycleObserver {

override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
owner.lifecycle.removeObserver(this)
update()
}
}

and use it in fragments onAttach (or another lifecycle method) like:

myActivity.lifecycle.addObserver(MyActivityObserver {
myOnActivityCreated()
})


Related Topics



Leave a reply



Submit