Vous n'avez pas besoin de remplacer instantiateItem
ni se fonder sur la compatibilité avec les systèmes internes de makeFragmentName
en créant manuellement des balises de fragment.
instantiateItem
est un public afin de pouvoir l'appeler dans onCreate
de votre activité entourée d'appels à startUpdate
y finishUpdate
comme décrit dans PagerAdapter
javadoc :
Un appel à la méthode startUpdate(ViewGroup) du PagerAdapter indique que le contenu du ViewPager est sur le point de changer. Un ou plusieurs appels à instantiateItem(ViewGroup, int) et/ou destroyItem(ViewGroup, int, Object) suivront, et la fin d'une mise à jour sera signalée par un appel à finishUpdate(ViewGroup).
Vous pouvez alors, par le biais de ce qui précède, stocker les références aux instances de vos fragments sur des variables locales si nécessaire. Voir l'exemple :
public class MyActivity extends AppCompatActivity {
Fragment0 tab0; Fragment1 tab1;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.myLayout);
ViewPager viewPager = (ViewPager) findViewById(R.id.myViewPager);
MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
((TabLayout) findViewById(R.id.tabs)).setupWithViewPager(viewPager);
adapter.startUpdate(viewPager);
tab0 = (Fragment0) adapter.instantiateItem(viewPager, 0);
tab1 = (Fragment1) adapter.instantiateItem(viewPager, 1);
adapter.finishUpdate(viewPager);
}
class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager manager) {super(manager);}
@Override public int getCount() {return 2;}
@Override public Fragment getItem(int position) {
if (position == 0) return new Fragment0();
if (position == 1) return new Fragment1();
return null; // or throw some exception
}
@Override public CharSequence getPageTitle(int position) {
if (position == 0) return getString(R.string.tab0);
if (position == 1) return getString(R.string.tab1);
return null; // or throw some exception
}
}
}
instantiateItem
essaiera d'abord d'obtenir des références à des instances de fragment existantes à partir de FragmentManager
. Seulement s'ils n'existent pas encore, il en créera de nouveaux à l'aide de getItem
de votre adaptateur et de les "stocker" dans le fichier FragmentManager
pour toute utilisation future.
MISE À JOUR 05/2022 : en fonction de ce commentaire la partie ci-dessous peut conduire à des performances sous-optimales dans l'implémentation actuelle.
En suivant la javadoc ci-dessus, vous devez toujours appeler instantiateItem
pour tous vos onglets entourés de startUpdate
/ finishUpdate
dans votre onCreate
même si vous n'avez pas besoin d'obtenir des références à vos fragments :
adapter.startUpdate(viewPager);
// ignoring return values of the below 2 calls, just side effects matter:
adapter.instantiateItem(viewPager, 0);
adapter.instantiateItem(viewPager, 1);
adapter.finishUpdate(viewPager);
Si vous ne le faites pas, vous risquez que vos instances de fragments ne soient jamais engagé a FragmentManager
: quand votre activité passe au premier plan instantiateItem
sera appelé automatiquement pour obtenir vos fragments, mais startUpdate
/ finishUpdate
mai pas (selon les détails d'implémentation) et ce qu'ils font fondamentalement est de commencer/commettre un FragmentTransaction
.
Ce site mai font que les références aux instances de fragment créées sont perdues très rapidement (par exemple lorsque vous faites pivoter votre écran) et recréées beaucoup plus souvent que nécessaire. Selon la "lourdeur" de vos fragments, cela peut avoir des conséquences non négligeables sur les performances.
De plus, dans ce cas, les instances des fragments stockés sur les vars locaux mai deviennent périmés : si la plate-forme Android tente de les obtenir à partir de FragmentManager
pour quelque raison que ce soit, il échouera et créera et utilisera donc de nouvelles variables, alors que vos variables feront toujours référence aux anciennes.