web-dev-qa-db-fra.com

onAttach () n'est pas appelé dans Fragment

Mon fragment n'appelle pas la méthode onAttach(context) lors de son lancement à partir de AppCompatActivity.

Fragment créant en 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" />

Mais si je le prolonge de support.v4.Fragment, appelez onAttach(context)!

Quel pourrait être le problème?

Bien sûr, je peux étendre tous les fragments à partir de v4.Fragment, mais je ne le veux pas. Est-ce une mauvaise pratique? Également le projet min sdk 14.

61
winston

Elle n'est pas appelée car cette méthode a été ajoutée à l'API 23. Si vous exécutez votre application sur un périphérique doté de l'API 23 (Marshmallow), onAttach(Context) sera appelé. onAttach(Activity) sera appelé sur toutes les versions Android précédentes.

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

Le support des bibliothèques de support est indépendant de la plateforme. Par conséquent, cela fonctionne sur toutes les versions de l'API.

128
sockeqwe

Alors que Google veut que nous arrêtions d'utiliser des API obsolètes

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

Est-ce si nouveau que ça ne s'appelle pas beaucoup. Vous devez également mettre en œuvre

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

Pour moi, elles sont identiques mais j'aime bien EMBRASSER et l'introduction d'une autre bibliothèque de support tend à doubler mon apk à environ 1 000 Ko. J'ai seulement mis à jour mon SDK hier.

La raison pour laquelle les types ne sont pas interchangeables ici, comme ils le sont dans de nombreux cas, est que la méthode utilisant Activity sera toujours appelée quand un Activity sera fourni car ils sont à la fois visibles publiquement et Activity est plus spécialisé que (en tant que sous-classe de ) Context donc aura priorité.

42
John

En plus des commentaires susmentionnés, il est important de noter que si vous essayez d'utiliser la fonction onAttach() pour mettre à jour les données contenues dans le fragment de l'activité parent, il est possible de rencontrer des problèmes lorsque la variable de collection de l'activité est Null ou vide lorsque le fragment est gonflé. À un moment donné du cycle de vie de votre activité, votre modèle de données peut changer et doit être mis à jour dans le fragment. Vous pouvez essayer d'obtenir une référence à un fragment déjà gonflé, mais vous constaterez au fur et à mesure que votre code parcourt que le code onAttach() ne se déclenche jamais, même lorsque vous utilisez le remplacement contenant un objet Context ou Activity.

Si vous essayez de créer un écouteur pour le fragment et de l'initialiser à partir de la méthode de rappel onAttach(), onAttach() ne se déclenchera pas à moins que vous ne fournissiez le paramètre de balise comme indiqué ci-dessous lors de l'ajout du fragment à l'activité:

// 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);
0
mrfilter