J'ai une interface de fragment avec des onglets en bas qui ouvrent différents fragments dans la vue principale.
J'ai un fragment particulier qui est une liste d'articles. Si l'utilisateur sélectionne l'un des éléments de cette liste, un autre fragment s'ouvre et contient un visualiseur qui défile horizontalement entre tous les éléments de la liste dans le fragment précédent. Cela fonctionne très bien.
Le visualiseur utilise un FragmentPagerAdapter pour afficher les éléments.
Le problème survient lorsque l'utilisateur sélectionne un élément dans la liste, l'affiche, puis appuie sur le bouton de la barre d'onglets pour revenir à la liste, puis sélectionne un autre élément. La deuxième fois qu'un élément est sélectionné, un écran vide apparaît à la place du visualiseur. Je ne reçois aucune erreur dans mon LogCat lorsque cela se produit.
Pourquoi le visualiseur n'apparaît-il que la première fois?
FragmentPagerAdapter:
public class ViewPagerAdapter extends FragmentPagerAdapter {
Cursor mCursor;
public ViewPagerAdapter(FragmentManager fm, Cursor c) {
super(fm);
mCursor = c;
}
public void changeCursor(Cursor c) {
mCursor = c;
this.notifyDataSetChanged();
}
@Override
public int getCount() {
if (mCursor == null) return 0;
else return mCursor.getCount();
}
@Override
public Fragment getItem(int position) {
mCursor.moveToPosition(position);
return TeamCardFragment.newInstance(mCursor, position);
}
}
PagerFragment:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle bundle = getArguments();
mCursorPosition = bundle.getInt(TeamCardCommon.BUNDLE_KEY_CURSOR_POSITION);
View mView = inflater.inflate(R.layout.team_card_master, container, false);
mViewPager = (ViewPager)mView.findViewById(R.id.team_card_master_view_pager);
mAdapter = new ViewPagerAdapter(getFragmentManager(), cursor);
new setAdapterTask().execute();
return mView;
}
private class setAdapterTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
return null;
}
@Override
protected void onPostExecute(Void result) {
mViewPager.setAdapter(mAdapter);
mViewPager.setCurrentItem(mCursorPosition);
}
}
FragmentPagerAdapter
etFragmentStatePagerAdapter
est dans le premier étant plus adapté pour quelques pages, il conserve tous les fragments en mémoire ayant ainsi les meilleures performances sur le changement de page, tandis que le dernier est plus adapté à beaucoup de pages, il détruit les fragments, ne gardant que leur état, c'est plus efficace en mémoire mais un peu plus lent au changement de page.J'ai réussi à résoudre ce problème en remplaçant
getFragmentManager()
pargetChildFragmentManager()
dans le fragment parent. Ce fragment parent instanciait un android.support.v4.app.FragmentPagerAdapter afin de contenir des fragments paginables (glissants), ce qui nécessite un gestionnaire de fragments dans le constructeur. À ce constructeur, j'ai passé la valeur de retour degetChildFragmentManager()
.Le lien de hackbod était essentiel ( https://developer.android.com/about/versions/android-4.2.html#NestedFragments ), qui a été trouvé dans cet article Fragments within Fragments
la source
FragmentStatePagerAdapter
résout pas la question posée ici. avec leFragmentStatePagerAdapter
fragment parentYourAdapter adapter = new YourAdapter (getChildFragmentManager());
doit être ajoutépour moi, je devais appeler ceci sur mon viewpager:
J'ai eu le problème où le viewpager n'était pas rafraîchissant et tout ce que j'ai vu était un écran blanc vierge où les fragments devraient être. Je passais dans getChildFragmentManager mais cela n'a pas aidé.
la source
Dans mon cas très particulier, où j'utilisais un CoordinatorLayout avec un AppBarLayout et le ViewPager, ce qui l'a résolu pour moi était de supprimer l'android: fitSystemWindows = "true" de mes propriétés xml AppBarLayout .
Ne me demandez pas pourquoi. Je sais que cela semble un peu ridicule et que cela ne devrait pas avoir de corrélation, mais c'était cette seule ligne la seule chose qui causait des problèmes car j'utilisais déjà getChildFragmentManager () dans mon adaptateur. J'ai passé une journée entière à déboguer mon code juste pour trouver ceci, donc j'espère que cela fera gagner du temps à quelqu'un d'autre.
la source
J'ai eu le même problème pour lequel j'ai changé l'adaptateur de
FragmentPagerAdapter
versFragmentStatePagerAdapter
etgetFragmentManager()
dans le fragment parent engetChildFragmentManager()
La raison derrière cela est
FragmentStatePagerAdapter
utile pour stocker un grand nombre de pages et la mémoire associée à chaque page visitée est moindre car elle ne conserve que l'état enregistré du fragment pendant que la page n'est pas visible. Cela réduit les frais généraux lors de la commutation entre les fragments.la source
Essayez de mettre
setOffscreenPageLimit (int limit)
sur ViewPager parent.Cela a fonctionné pour moi comme un charme.
Dans mon cas, j'avais un fragment à l'intérieur
TabLayout
avecViewPager.
Et un autre à l'
ViewPager
intérieur de ce fragment. La première fois, tout fonctionne bien, mais lorsque je change d'onglet et que je reviens, une partie de mon fragment est devenue vierge.la source
Cela vous aiderait.
la source
Nous avons contourné ce problème en réimplémentant les éléments du pagineur de vues en tant que vues standard plutôt qu'en fragments et en modifiant l'adaptateur en conséquence.
la source
J'obtenais ce même problème sur Xamarin Android avec un écran vide la deuxième fois. La configuration de ce qui suit l'a corrigé pour moi.
la source
Vous pouvez également initialiser l'adaptateur pour les cas où vous rencontrez cette erreur lorsque votre application est réduite et appelée ultérieurement.
la source
J'ai eu la même chose, la deuxième fois que j'appelle l'adaptateur de téléavertisseur, la vue enfant renvoie une NullPointerException. Et changer l'adaptateur dans FragmentStatePagerAdapter résout également mon problème.
la source
Changer
FragmentPagerAdapter
enFragmentStatePagerAdapter
utilisationgetChildFragmentManager()
au lieu degetFragmentManager()
getChildFragmentManager()
- car selon la documentation, il renverra un FragmentManager privé pour placer et gérer des fragments à l'intérieur de ce fragment. Pendant ce tempsgetFragmentManager()
, retournera le FragmentManager pour interagir avec les fragments associés à cette activitéla source
la classe ViewPagerAdapter étend FragmentStatePagerAdapter ce travail pour moi essayez ceci
la source