Nous souffrons d'un problème très étrange avec ViewPager ici. Nous intégrons des listes sur chaque page ViewPager et déclenchons notifyDataSetChanged à la fois sur l'adaptateur de liste et l'adaptateur de pager de vue lors de la mise à jour des données de liste.
Ce que nous observons, c'est que parfois, la page ne met pas à jour son arborescence de vues, c'est-à-dire qu'elle reste vierge, ou parfois même disparaît lors de la pagination. Lors de la pagination d'avant en arrière plusieurs fois, le contenu réapparaît soudainement. Il semble qu'Android manque une mise à jour de vue ici. J'ai également remarqué que lors du débogage avec la visionneuse de hiérarchie, la sélection d'une vue la fera toujours réapparaître, apparemment parce que la visionneuse de hiérarchie oblige la vue sélectionnée à se redessiner.
Cependant, je ne pouvais pas faire fonctionner cela par programme; invalider la vue de liste, ou même le pager de vue entier, n'avait aucun effet.
C'est avec la bibliothèque compatibilité-v4_r7. J'ai également essayé d'utiliser la dernière révision, car elle prétend résoudre de nombreux problèmes liés à l'affichage du pager, mais cela a aggravé les choses (par exemple, les gestes étaient interrompus pour ne plus me permettre de parcourir toutes les pages parfois.)
Quelqu'un d'autre rencontre-t-il également ces problèmes ou avez-vous une idée de ce qui pourrait en être la cause?
la source
Si le
ViewPager
est défini dans un fragment avec unFragmentPagerAdapter
, utilisezgetChildFragmentManager()
au lieu degetSupportFragmentManager()
comme paramètre pour initialiser votreFragmentPagerAdapter
.mAdapter = new MyFragmentPagerAdapter(getChildFragmentManager());
Au lieu de
mAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
la source
getItem()
sur unFragmentPagerAdapter
qui était imbriqué dans un fragment recréé.J'ai eu exactement le même problème mais j'ai en fait détruit la vue dans destroyItem (j'ai pensé). Le problème était cependant que je l'ai détruit en utilisant
viewPager.removeViewAt(index);
insted ofviewPager.removeView((View) object);
Faux:
@Override public void destroyItem(ViewGroup viewPager, int position, Object object) { viewPager.removeViewAt(position); }
Droite:
@Override public void destroyItem(ViewGroup viewPager, int position, Object object) { viewPager.removeView((View) object); }
la source
ViewPager essaie de faire des choses intelligentes autour de la réutilisation des éléments, mais il vous oblige à renvoyer de nouvelles positions d'éléments lorsque les choses ont changé. Essayez d'ajouter ceci à votre PagerAdapter:
public int getItemPosition (Object object) { return POSITION_NONE; }
Il indique essentiellement à ViewPager que tout a changé (et le force à tout ré-instancier). C'est la seule chose à laquelle je peux penser du haut de ma tête.
la source
return POSITION_NONE;
,forces it to re-instantiate everything
mais dans mon cas, je ne veux pas tout ré-instancier , alors serait-il possible de supprimerview
sans effacer les éléments existants? S'il vous plaît laissez-moi savoirJ'ai essayé trop de solutions mais a
viewPager.post()
fonctionné de manière inattenduemAdapter = new NewsVPAdapter(getContext(), articles); viewPager.post(new Runnable() { @Override public void run() { viewPager.setAdapter(mAdapter); } });
la source
La bibliothèque de support Android a une activité de démonstration qui comprend un ViewPager avec un ListView sur chaque page. Vous devriez probablement jeter un œil et voir ce qu'il fait.
Dans Eclipse (avec Android Dev Tools r20):
New > Android Sample Project
Support4Demos
Android Tools > Add Support Library
Fragment
, puisPager
Le code pour cela est au format
src/com.example.android.supportv4.app/FragmentPagerSupport.java
. Bonne chance!la source
J'ai rencontré cela et j'ai eu des problèmes très similaires. Je l'ai même demandé sur le débordement de pile.
Pour moi, dans le parent du parent de ma vue, quelqu'un a sous
LinearLayout
-classé et remplacérequestLayout()
sans appelersuper.requestLayout()
. Cela a empêchéonMeasure
etonLayout
d'être appelé sur mon ViewPager (bien que hierarchyviewer les appelle manuellement). Sans être mesurés, ils s'afficheront comme vides dans ViewPager.Vérifiez donc vos vues contenant. Assurez-vous qu'ils sous-classe de View et ne remplacent pas aveuglément requestLayout ou quelque chose de similaire.
la source
Eu le même problème, qui est quelque chose à voir avec
ListView
(parce que ma vue vide apparaît bien si la liste est vide). Je viens d'appelerrequestLayout()
la problématiqueListView
. Maintenant ça dessine bien!la source
J'ai rencontré ce même problème lors de l'utilisation d'un ViewPager et d'un FragmentStatePagerAdapter. J'ai essayé d'utiliser un gestionnaire avec un délai de 3 secondes pour appeler invalidate () et requestLayout () mais cela n'a pas fonctionné. Ce qui a fonctionné a été de réinitialiser la couleur d'arrière-plan de viewPager comme suit:
MyFragment.java
private Handler mHandler; private Runnable mBugUpdater; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = new ViewPager(getActivity()); //...Create your adapter and set it here... mHandler = new Handler(); mBugUpdater = new Runnable(){ @Override public void run() { mVp.setBackgroundColor(mItem.getBackgroundColor()); mHandler = null; mBugUpdater = null; } }; mHandler.postDelayed(mBugUpdater,50); return rootView; } @Override public void onPause() { if(mHandler != null){ //Remove the callback if it hasn't triggered yet mHandler.removeCallbacks(mBugUpdater); mHandler = null; mBugUpdater = null; } super.onPause(); }
la source
J'ai eu un problème avec les mêmes symptômes, mais une cause différente qui s'est avérée être une erreur stupide de ma part. Je pensais l'ajouter ici au cas où cela aiderait quelqu'un.
J'avais un ViewPager utilisant FragmentStatePagerAdapter qui avait auparavant deux fragments, mais j'en ai ajouté plus tard un troisième. Cependant, j'ai oublié que la limite de page par défaut hors écran est de 1 - donc, lorsque je passerais au nouveau troisième fragment, le premier serait détruit, puis recréé après le retour. Le problème était que mon activité était en charge de notifier ces fragments pour initialiser leur état d'interface utilisateur. Cela s'est produit lorsque l'activité et les cycles de vie des fragments étaient les mêmes, mais pour y remédier, j'ai dû modifier les fragments pour initialiser leur propre interface utilisateur au cours de leur cycle de vie de démarrage. En fin de compte, j'ai également fini par changer setOffscreenPageLimit à 2 afin que les trois fragments soient conservés en vie à tout moment (sans danger dans ce cas car ils n'étaient pas très gourmands en mémoire).
la source
J'ai eu un problème similaire. Je mets en cache des vues parce que je n'ai besoin que de 3 vues
ViewPager
. Lorsque je glisse vers l'avant, tout va bien, mais lorsque je commence à glisser vers l'arrière, une erreur se produit, cela dit que "ma vue a déjà un parent". La solution consiste à supprimer manuellement les éléments inutiles.@Override public Object instantiateItem(ViewGroup container, int position) { int localPos = position % SIZE; TouchImageView view; if (touchImageViews[localPos] != null) { view = touchImageViews[localPos]; } else { view = new TouchImageView(container.getContext()); view.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); touchImageViews[localPos] = view; } view.setImageDrawable(mDataModel.getPhoto(position)); Log.i(IRViewPagerAdpt.class.toString(), "Add view " + view.toString() + " at pos: " + position + " " + localPos); if (view.getParent() == null) { ((ViewPager) container).addView(view); } return view; } @Override public void destroyItem(ViewGroup container, int position, Object view) { // ((ViewPager) container).removeView((View) view); Log.i(IRViewPagerAdpt.class.toString(), "remove view " + view.toString() + " at pos: " + position); } .................. private static final int SIZE = 3; private TouchImageView[] touchImageViews = new TouchImageView[SIZE];
la source
Pour moi, le problème revenait à l'activité après l'arrêt du processus d'application. J'utilise un adaptateur de pager de vue personnalisé modifié à partir des sources Android. Le pageur de vue est intégré directement dans l'activité.
Appel
viewPager.setCurrentItem(position, true);
(avec animation) après avoir défini les données et notifyDataSetChanged () semble fonctionner, mais si le paramètre est défini sur false, ce n'est pas le cas et le fragment est vide. C'est un cas de pointe qui peut être utile à quelqu'un.
la source