Il semble qu'un grand nombre de personnes qui consultent cette question cherchent un moyen de faire référence à l'interface de l'entreprise. Fragments
créé par FragmentPagerAdapter
/ FragmentStatePagerAdapter
. Je voudrais proposer ma solution à ce problème sans m'appuyer sur la en interne créé tags
que les autres réponses ici utilisent.
En prime, cette méthode devrait également fonctionner avec FragmentStatePagerAdapter
. Voir les notes ci-dessous pour plus de détails.
Problème des solutions actuelles : dépendance à l'égard du code interne
Un grand nombre des solutions que j'ai vues pour cette question et d'autres questions similaires reposent sur l'obtention d'une référence à la base de données existante de l'entreprise. Fragment
en appelant FragmentManager.findFragmentByTag()
et en imitant le balise créée en interne : "android:switcher:" + viewId + ":" + id
. Le problème, c'est que vous vous appuyez sur le code source interne, qui, comme nous le savons tous, n'est pas garanti de rester le même pour toujours. Les ingénieurs Android de Google pourraient facilement décider de modifier le code source de l'application. tag
ce qui casserait votre code en vous laissant dans l'incapacité de trouver une référence à la structure existante de la Fragments
.
Solution alternative sans recours à l'interne tag
Voici un exemple simple de la façon d'obtenir une référence à l'objet Fragments
retourné par FragmentPagerAdapter
qui ne s'appuie pas sur le système interne tags
sur le Fragments
. La clé est de passer outre instantiateItem()
et y enregistrer les références au lieu de de dans getItem()
.
public class SomeActivity extends Activity {
private FragmentA m1stFragment;
private FragmentB m2ndFragment;
// other code in your Activity...
private class CustomPagerAdapter extends FragmentPagerAdapter {
// other code in your custom FragmentPagerAdapter...
public CustomPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// Do NOT try to save references to the Fragments in getItem(),
// because getItem() is not always called. If the Fragment
// was already created then it will be retrieved from the FragmentManger
// and not here (i.e. getItem() won't be called again).
switch (position) {
case 0:
return new FragmentA();
case 1:
return new FragmentB();
default:
// This should never happen. Always account for each position above
return null;
}
}
// Here we can finally safely save a reference to the created
// Fragment, no matter where it came from (either getItem() or
// FragmentManger). Simply save the returned Fragment from
// super.instantiateItem() into an appropriate reference depending
// on the ViewPager position.
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
// save the appropriate reference depending on position
switch (position) {
case 0:
m1stFragment = (FragmentA) createdFragment;
break;
case 1:
m2ndFragment = (FragmentB) createdFragment;
break;
}
return createdFragment;
}
}
public void someMethod() {
// do work on the referenced Fragments, but first check if they
// even exist yet, otherwise you'll get an NPE.
if (m1stFragment != null) {
// m1stFragment.doWork();
}
if (m2ndFragment != null) {
// m2ndFragment.doSomeWorkToo();
}
}
}
o si vous préférez travailler avec tags
au lieu des variables membres de la classe/références à la Fragments
vous pouvez également saisir le tags
fixé par FragmentPagerAdapter
de la même manière : NOTE : ceci ne s'applique pas à FragmentStatePagerAdapter
puisqu'il ne définit pas tags
lors de la création de son Fragments
.
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
// get the tags set by FragmentPagerAdapter
switch (position) {
case 0:
String firstTag = createdFragment.getTag();
break;
case 1:
String secondTag = createdFragment.getTag();
break;
}
// ... save the tags somewhere so you can reference them later
return createdFragment;
}
Notez que cette méthode ne repose PAS sur l'imitation de l'interface interne de l'entreprise. tag
fixé par FragmentPagerAdapter
et utilise plutôt des API appropriées pour les récupérer. De cette façon, même si le tag
des changements dans les futures versions de l SupportLibrary
vous serez toujours en sécurité.
N'oubliez pas qu'en fonction de la conception de votre Activity
le Fragments
sur lequel vous essayez de travailler peut ou peut ne pas exister encore, donc vous devez en tenir compte en faisant null
vérifications avant d'utiliser vos références.
De même, si au lieu de vous travaillez avec FragmentStatePagerAdapter
alors vous ne voulez pas garder des références dures à vos Fragments
parce que vous pourriez en avoir beaucoup et que les références dures les garderaient inutilement en mémoire. Au lieu de cela, enregistrez les Fragment
références en WeakReference
au lieu des variables standard. Comme ceci :
WeakReference<Fragment> m1stFragment = new WeakReference<Fragment>(createdFragment);
// ...and access them like so
Fragment firstFragment = m1stFragment.get();
if (firstFragment != null) {
// reference hasn't been cleared yet; do work...
}