onAttach() not called in Fragment
Asked Answered
D

3

64

My Fragment doesn't call onAttach(context) method when it launched from AppCompatActivity.

Fragment creating in XML:

<fragment
    android:id="@+id/toolbar"
    class="package.MainToolbarFragment"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:layout="@layout/fragment_main_toolbar" />

But if I extends it from support.v4.Fragment, onAttach(context) call !

What could be the problem?

Of course, I can extend all fragments from v4.Fragment, but I don't want it. Is it bad practice? Also project min sdk 14.

Deedradeeds answered 16/9, 2015 at 9:23 Comment(1)
I think you should visit here #32083553 Hope it clarifies.Calvaria
L
131

It's not called because this method has been added in API 23. If you run your application on a device with API 23 (marshmallow) then onAttach(Context) will be called. On all previous Android Versions onAttach(Activity) will be called.

http://developer.android.com/reference/android/app/Fragment.html#onAttach(android.app.Activity)

Support libraries fragment is platform independent. Hence it works on all API versions.

Laurentia answered 20/9, 2015 at 11:43 Comment(4)
Any idea if I should implement them both (for api 23 devices)? Does the onAttach(Activity) still being called in API 23?Quinton
@Laurentia Kudos to you. I had mistakenly imported the new Fragment class , been looking at this for a few hours without noticing. Thank youWormseed
@AvivBenShabat you should rather used the app compat version of this API and implement just the onAttach(Context context) version of the methodGewgaw
Nowadays you should be using androix fragments.Predict
P
43

While Google wants us to stop using deprecated API's

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    ...

Is so new that it isn't widely called. You need to also implement

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    ...

For me they are identical but I like to KISS and introducing another support library tends to double my apk to about 1000kb. I only updated my SDK yesterday.

The reason the types are not interchangeable here, as they are in many instances, is that the method taking an Activity will still be called when an Activity is provided as they are both publicly visible and Activity is more specialised than (as a sub class of) Context so will take precedence.

Pneumograph answered 19/9, 2015 at 10:48 Comment(3)
Using support library is not that bad. Your approach will lead to some weird behavior such as onStart() not getting called every time.Handel
@yehe perhaps you could elaborate on what the support library does in addition to implement both methods? I view it as a package of mostly polyfil fixes with some of the theme and glitter of newer versions to give old devices a face lift. I don't say that is bad, just that when I am using a framework on top of Android it's mostly irrelevant bloat.Pneumograph
Implementing two methods doesn't work on many devices based on my experience. Have tested on various Nexus, Samsung phones, it will not work in many of them. Debugging shows onAttach(Activity activity) doesn't get called every time. Using support library, I never came across any weird errors.Handel
L
0

In addition to the aforementioned comments, I believe it is important to note that if you are attempting to use the onAttach() to update data contained inside the fragment from the parent Activity, it is possible to run into issues when the collection variable inside the Activity is null or empty when the fragment is inflated. At some point inside your Activity's life cycle, your data model may change and need to be updated inside the fragment. You might attempt to get a reference to a fragment already inflated, but find as you step through your code that onAttach() never fires, even when using the override containing a Context or Activity object.

If you are attempting to create a listener for the fragment and initialize the listener from the onAttach() callback method, onAttach() will not fire unless you provide the tag parameter as shown below when adding the fragment to the Activity:

// in the Activity
getFragmentManager().beginTransaction()
    .add(
        R.id.fragmentContainer,
        CustomFragment.newInstance(customDataSource),
        CustomFragment.TAG // Must be passed in for the code below to work
    ).commit();


// Getting a reference to the fragment later on (say to update your data model inside the fragment (in onActivityResult())

CustomFragment fragmentDelegate = (CustomFragment) getFragmentManager().findFragmentByTag(CustomFragment.TAG);
fragmentListener.updateDataSource(customDataSource);
Lahr answered 16/7, 2017 at 1:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.