Where is FragmentHostCallback created in Fragment? - android

When I checked lifecycle of fragment I found something that I do not understand.
FragmentHostCalback
Fragments may be hosted by any object; such as an Activity. In order to host fragments, implement FragmentHostCallback, overriding the methods applicable to the host.
Question
Where created FragmentHostCallback in Fragment?
I think FragmentHostCallback created at onInflate or onAttach. However, I couldn't find any code related to creating FragmentHostCallback there.

Fragments themselves don't host Fragments - as mentioned, it is an Activity or equivalent object that creates a FragmentHostCallback object. For example, FragmentActivity contains its own implementation of FragmentHostCallback called HostCallbacks.
You never interact with this object directly, rather, the FragmentHostCallback is passed to the FragmentController.createController(), which is what FragmentActivity, in this case, uses to trigger lifecycle changes and other signals from the Activity to the FragmentManager that you actually interact with.

Related

Why are lifecycle methods in fragments public while those of activity are protected?

The activity is protected for encapsulation within the framework package android.app and subclasses according to this link so why are fragments lifecycle methods having a public access modifier?
put simply, that's because your activity (internally not by you) calls the functions like onCreateView()
or in a more abstract and reasoning explanation, because an activity can contain fragments and for fragment-activity communication.
public methods are needed to access functionalities like, findFragmentById(),
an activity can exist as an independent entity. the context is present which is a primary requirement for performing an US related operation in android. a fragment does not have a context of its own(the getActivity() method provides context in a fragment)
from the documentation
Though a Fragment's lifecycle is tied to its owning activity, it has its own wrinkle on the standard activity lifecycle. It includes basic activity lifecycle methods such as onResume(), but also important are methods related to interactions with the activity and UI generation.
EDIT:going by the similar methodology of the answer you linked, fragments (for backward compatibility) are also present as android.support.v4.app.Fragment . But the Activity class is only in android.app.So in order to ensure backward compatibility,the public methods are present in this case

Fragment implementation - Using google's document as an example

I am reading google developer's article on Fragment implementation. I am stuck at one point in the session "Creating event callbacks to the activity".
It says that when Fragment A, which contains a list of articles' title, wants to communicate with Article Fragment, which shows the content of the article, Fragment A should implement an interface OnArticleSelectedListener. A listener is set in the activity hosting the two fragments, and the listener will send information to Article Fragment.
My problem is that, why don't we simply implement an interface in Article Fragment listening to Fragment A's selection? I know there must be a reason, but I just don't get it.
My Attempt:
Is it because we cannot find a reference to Article Fragment in Fragment A? We could only find the reference of Article Fragment from the hosting activity.
Many Thx.
Fragments can not communicate with each other. Activity is not only a Host but also acts as a middle man between two or more fragments.
(taken from developer.android.com)
Although a Fragment is implemented as an object that's independent from an Activity and can be used inside multiple activities, a given instance of a fragment is directly tied to the activity that contains it.
In some cases, you might need a fragment to share events with the activity. A good way to do that is to define a callback interface inside the fragment and require that the host activity implement it. When the activity receives a callback through the interface, it can share the information with other fragments in the layout as necessary.

What is the difference creating event callback or the activity itself within a fragment?

Lets say I will be using several fragments(Action1Fragment, Action2Fragment etc.) within an activity(ActionActivity). I want to access some elements of activity object, or call some methods of ActionActivity. It is generally offered to create a event callback . What if I keep a reference to ActionActivity within Action1Fragment instead of keeping a reference to CallBackInterface which is actually implemented by ActionActivity since I will be using these fragments only within a particular activity.
I am kinda confused by the idea that Activity might be dead while reference of interface might still be alive(it sounds ridiculous when I read it again but it is OK if I managed to explain myself).
The Android Developer tutorials recommend that you use a callback interface on your fragments. The activity that hosts the fragment must implement the callback interface. The fragment does getActivity() and casts it to the callback interface, and then makes the callback.
This is the recommended way to promote a more modular design. It would not matter if your fragments will only ever work inside one activity. But if you want to make more generic fragments that could be used by different activities, then the above design pattern starts to become useful. (For example: a telephones fragment inside an person fragment and a company fragment.)
Suppose you do it the other way: the fragment does getActivity() and casts it to PersonActivity. The fragment then has access to all the public methods of PersonActivity. But this design pattern becomes much more ugly when you need the other activity to also use the fragment. The fragment would then have to be changed to first try and cast to PersonActivity, and if that throws, try the CompanyActivity.
The recommended design pattern basically gives you a way to make an activity compatible with the fragment instead of vice versa. The fragment only knows about the callback interface and not about any of the activities itself. The activities do know about the fragment because they implement the callback interface but they already knew about it because they constructed and initialized an instance of it.
Does that make sense?

Use fragments in fragment

I am using FragmentStatePagerAdapter to create view pager for a list of objects. Each page is a fragment.
However, on that page, I am also using fragments to display some other data.
I got problem when doing this. I wonder can I put fragments in fragment. Or any other solutions to work this out?
Nested fragments are not supported by current fragment implementation (it was answered by Diane, Android engineer as well here:
Nested fragments are not currently supported. Trying to put a fragment
within the UI of another fragment will result in undefined and likely
broken behavior.
But it does not mean it is not doable - it can be achieved, however requires writing some more code than just fragment. There's comment in same thread by other user:
I managed this by extending FragmentActivity, FragmentManager, and
FragmentTransaction. Basic premise is extend DeferringFragmentActivity
in my activities, providing same api so no other code changes. When I
call getFragmentManager, I get an instance that
DeferringFragmentManager, and when I call beginTransaction, I get a
DeferredTransaction. This transaction stores POJOs with the called
method and arguments. When commit is call, we look for any pending
DeferredTransactions first. Once all transactions have been committed,
we start a real transaction and run all the stored methods with args
In general - unless you are desperated, just redesign your layout.
Fragments cannot hold other fragments.
It's not supported (errors with state)
I have used Fragments inside an Fragment in a project. The way I ended up doing is adding these inside fragments via code and using the fragment attached to the activity as a "proxy" for the other, so on the oncreateview() of the fragment you instantiate the inside fragments, ondestroyview() you remove the inside fragments and so on.

Bug in the official Android Fragments training sample?

It seems to me that there must be a bug in the Android Fragments demo.
As background, Fragments are apparently sometimes instantiated by the Android OS and thus need a public no-arg constructor:
All subclasses of Fragment must include a public empty constructor.
The framework will often re-instantiate a fragment class when needed,
in particular during state restore, and needs to be able to find this
constructor to instantiate it. If the empty constructor is not
available, a runtime exception will occur in some cases during state
restore.
But the NewsReader demo from the official Android training on Fragments constructs the HeadlinesFragment class and configures it with setOnHeadlineSelectedListener(this) from NewsReaderActivity.onCreate().
If the Android OS re-instantiates this fragment, the mHeadlineSelectedListener field will be null because HeadlinesFragment doesn't save or restore its state. It can't anyhow, because I believe it's impossible to persist a reference to an Activity.
Furthermore, I noticed that the Fragment documentation states:
It is strongly recommended that subclasses do not have other
constructors with parameters, since these constructors will not be
called when the fragment is re-instantiated; instead, arguments can be
supplied by the caller with setArguments(Bundle) and later retrieved
by the Fragment with getArguments().
On the other hand, it seems they perform instantiation and configuration (sort-of) correctly in the preceding FragmentBasics example. I say "sort of" because for some reason they directly instantiate the HeadlinesFragment rather than via SupportFragmentManager, as is done in the NewsReader demo. Regardless, they don't make the apparent mistake of calling a setter in HeadlinesFragment from MainActivity, but instead let HeadlinesFragment take responsibility for finding the OnArticleSelectedListener, where it does so during onAttach().
Is this a bug in the NewsReader example or am I missing something? In the meantime, I've submitted an Android documentation issue.

Categories

Resources