Is there any misunderstanding about the onActivityCreated fragment callback? - android

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

Related

MVP: Best practice to manage Activities and Fragments

I have an Activity with two Fragments. I decided to have one presenter for each "view". So 1 presenter for the main Activity, 1 for the first fragment, and 1 presenter for the second fragment.
I have uses-cases in which I don't know where which code goes.
The first is where to manage fragments with fragment manager ? Do I have to do calls like "beginTransaction().add" in the activity or in his presenter ?
The second is, when the user tap on a button in the activity, I've to do some things in the current fragment. Do I have to call the presenter of the activity which will call the fragment's method wanted, or directly in the method onClick in the activity I call this fragment's method?
PS: I don't want to use any lib/framework
The first is where to manage fragments with fragment manager ? Do I
have to do calls like "beginTransaction().add" in the activity or in
his presenter ?
Everything that is Android API related should be inside the Activity. So, beginTransaction() is a method of the FragmentManager and this is part of the Android API. The Activity is the contract between your app and the operating system. The presenter should not even know that it is used for an Android app. If you press a button inside the Activity for instance it goes like this:
Inside event handler method which is inside your Activity you do this:
Call activityPresenter.onButtonClicked() and it will call activityView.presentWhatTheButtonClickDid()
The second is, when the user tap on a button in the activity, I've to
do some things in the current fragment. Do I have to call the
presenter of the activity which will call the fragment's method
wanted, or directly in the method onClick in the activity I call this
fragment's method?
You would indirectly call the Fragment method via its presenter.
Inside event handler method which is inside your Activity:
Call activityPresenter.onButtonClicked() and it will call
fragmentPresenter.onButtonClicked() and it will calls
fragmentView.presentResult()
So, as you see the Activitiy's presenter needs to know the Fragment's presenter.
*You should not name your presenters with "activity" or "fragment" in its name to keep things abstract. I merely did this for simplicity.

what is the different between onCreate() and onCreateView() lifecycle methods in Fragment?

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

handling Fragments on Config Change

My application contains two fragments.
My Android manifest file contains the following line:
"android:configChanges="orientation|screenSize"
which I need for the second fragment. I don't want its onCreateView() or other method to be called an orientation change.
But my first fragment needs onCreateView() to be called when orientation changes. Since the manifest file contains the above line, the onCreateView() method is not called. Can anyone help me in sorting out this to make onCreateView() to be called when orientation changes for specific fragment?
I believe setRetainInstance() is the function you need.
From documentation:
Control whether a fragment instance is retained across Activity
re-creation (such as from a configuration change). This can only be
used with fragments not in the back stack. If set, the fragment
lifecycle will be slightly different when an activity is recreated:
onDestroy() will not be called (but onDetach() still will be, because
the fragment is being detached from its current activity).
onCreate(Bundle) will not be called since the fragment is not being
re-created.
onAttach(Activity) and onActivityCreated(Bundle) will
still be called.

onAttach activity is null

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();

Accessing the Activity from a Fragment

I'm trying to change the activity title from a fragment (in this case, it's an android.support.v4.app.Fragment). To this end, I save the activity in an attribute on the fragment when onAttach() is called on the fragment. According to the docs, onAttach() should be called before onCreateView(), which I'm using to request some data used to fill up the view. When I kick off the thread for the network retrieval, I want to indicate that in the title, so I'm trying to call this.activity.setTitle() from the Fragment. However, that keeps throwing a NullPointerException. What am I missing here?
You can access the Activity in a Fragment using getActivity(). It can be called safely as soon as onActivityCreated() was called on the Fragment. Before that, it might not be there or might not have been fully initialized yet.
If your thread starts before that, just note the fact somewhere in your Fragment and only change the title after onActivityCreated was called.
Nowadays you can call requiredActivity() too that return FragmentActivityobject and if fragment doesn't come from an Activity, method throws a IllegalStateException

Categories

Resources