Pour extraire des fragments d'un ViewPager il y a beaucoup de réponses ici et sur d'autres, de SORTE threads / blogs. Tous ceux que j'ai vu est cassé, et ils ont généralement l'impression de tomber dans l'un des deux types énumérés ci-dessous. Il y a d'autres solutions valables si vous ne voulez attraper l'actuel fragment, comme cette autre réponse sur ce fil.
Si vous utilisez FragmentPagerAdapter
voir ci-dessous. Si vous utilisez FragmentStatePagerAdapter
sa peine de regarder cette. L'accaparement des indices qui ne sont pas actuellement dans une FragmentStateAdapter n'est pas aussi utile que par la nature de ces va être complètement démoli est allé hors de la vue / de offScreenLimit limites.
LES MAUVAISES FAÇONS
Faux: gérer votre propre liste interne des fragments, ajouté lors de l' FragmentPagerAdapter.getItem()
est appelé
- Généralement à l'aide d'un
SparseArray
ou Map
- Pas l'un des nombreux exemples que j'ai vu des comptes pour les événements de cycle de vie, donc cette solution est fragile. En tant que
getItem
n'est appelée la première fois qu'une page est affichée (ou obtenu si votre ViewPager.setOffscreenPageLimit(x)
> 0) dans l' ViewPager
, si l'hébergement Activity
/ Fragment
est tué ou redémarré puis l'interne SpaseArray
seront effacées lorsque la coutume FragmentPagerActivity est recréé, mais derrière les coulisses, le ViewPagers interne fragments seront recréés, et getItem
va PAS être appelé pour toute de l'index, de sorte que la possibilité d'obtenir un fragment de l'indice seront perdus à jamais. Vous pouvez tenir compte de cette par la sauvegarde et la restauration de ces références de fragments via FragmentManager.getFragment()
et putFragment
, mais cela commence à être très salissant à mon humble avis.
-
EDIT: un semblable, mais non du cycle de vie de la rupture approche consiste à crochet en
ViewPager.instantiateItem()
au lieu de getItem
comme le premier sera appelé à chaque fois que l'index est créé / consulté. Voir cette réponse
Faux: Construire votre propre id de balise correspond à ce est utilisé sous le capot en FragmentPagerAdapter
et de l'utiliser pour récupérer les Fragments de page de l' FragmentManager
- C'est mieux de sorte qu'il s'adapte avec la perdre-fragment-références problème interne, solution de matrice, mais comme l'a justement souligné dans les réponses ci-dessus et ailleurs sur le net, il se sent hacky comme un privé méthode interne d'
ViewPager
qui pourrait changer à tout moment ou pour toute version de l'OS.
La méthode c'est recréé pour cette solution
private static String makeFragmentName(int viewId, long id) {
return "android:switcher:" + viewId + ":" + id;
}
LA bonne FAÇON: Construire votre propre FragmentViewPager
Construire votre propre FragmentViewPager
classe à partir de la source de la dernière support lib et de modifier la méthode utilisée en interne pour générer le fragment de balises. Vous pouvez le remplacer avec le ci-dessous. Ceci a l'avantage que vous connaissez le tag de la création ne changera jamais et de ne pas répondre à une api privée / méthode, qui est toujours dangereux.
/**
* @param containerViewId the ViewPager this adapter is being supplied to
* @param id pass in getItemId(position) as this is whats used internally in this class
* @return the tag used for this pages fragment
*/
public static String makeFragmentName(int containerViewId, long id) {
return "android:switcher:" + containerViewId + ":" + id;
}
Alors que le doc a dit, quand vous voulez prendre un fragment utilisé pour un indice de simplement appeler quelque chose comme cette méthode (que vous pouvez mettre dans la coutume FragmentPagerAdapter
ou une sous-classe) d'être au courant le résultat peut être null si getItem n'a pas encore été appelé pour cette page, c'est à dire son pas encore été créé.
/**
* @return may return null if the fragment has not been instantiated yet for that position - this depends on if the fragment has been viewed
* yet OR is a sibling covered by {@link android.support.v4.view.ViewPager#setOffscreenPageLimit(int)}. Can use this to call methods on
* the current positions fragment.
*/
public @Nullable Fragment getFragmentForPosition(int position)
{
String tag = makeFragmentName(mViewPager.getId(), getItemId(position));
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
return fragment;
}
C'est une solution simple et résout les problèmes dans les deux autres solutions trouvées un peu partout sur le web