Empêcher ViewPager de détruire les vues hors écran

133

J'ai un ViewPager connecté à un FragmentPagerAdapter qui affiche trois fragments. Le ViewPager semble détruire la vue d'un fragment hébergé lorsqu'il est à plus d'un balayage de la position actuelle.

Ces vues sont toutes des listes simples et cette optimisation est complètement inutile, je voudrais donc la désactiver. Cela pose des problèmes visuels car les listes ont des animations de mise en page qui leur sont appliquées et ces animations sont rejouées après avoir été détruites et recréées. Il montre également l'animation d'introduction de la barre de défilement à chaque fois (où la barre de défilement est brièvement visible pour indiquer que le défilement est possible), ce qui peut être gênant, et la position de défilement actuelle de l'utilisateur est perdue dans le processus.

Il ne charge pas non plus le troisième fragment avant le premier balayage, ce qui est problématique car chaque fragment gère ses propres appels de service et je préférerais que les trois se déclenchent en même temps lorsque l'activité se charge. Avoir le troisième appel de service retardé est loin d'être idéal.

Existe-t-il un moyen de convaincre ViewPager d'arrêter ce comportement et de simplement garder tous mes fragments en mémoire?

chefgon
la source

Réponses:

332

En révision 4 du Support Package, une méthode a été ajoutée à ViewPager qui vous permet de spécifier le nombre de pages hors écran à utiliser, plutôt que la valeur par défaut qui est 1.

Dans votre cas, vous souhaitez spécifier 2, pour que lorsque vous êtes sur la troisième page, la première ne soit pas détruite, et vice-versa.

mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(2);
David Snabel-Caunt
la source
une idée comment faire cela sur un coverflow?
josephus
4
Bonjour. Dans ce sur quoi je travaille, les fragments / pages sont créés dynamiquement, donc il y a un nombre indéfini de fragments probables. Dans ce cas, il passe généralement à 10 ou moins. Ne serait-ce pas une mauvaise utilisation de la mémoire d'utiliser cette solution sur autant de pages? Les fragments ne retiendront que la vue, d'ailleurs. Merci!
mahkie
Cette méthode génère: "java.lang.IllegalStateException: Fragment déjà ajouté:" erreur pour mon application.
alicanbatur
Merci beaucoup. Cela a vraiment fonctionné. J'ai aussi eu le même problème que @chefgon.
Prashant
@mahie les solutions ci-dessus si pour Ceci est offert comme une optimisation. Si vous connaissez à l'avance le nombre * de pages que vous devrez prendre en charge ou si vous avez mis en place des mécanismes de chargement paresseux * sur vos pages, la modification de ce paramètre peut avoir des avantages en termes de fluidité perçue * des animations de pagination et de l'interaction. Si vous avez un petit nombre de pages (3-4) * que vous pouvez garder actives en même temps, moins de temps sera consacré à la mise en page pour * les sous-arbres de vue nouvellement créés au fur et à mesure que les pages utilisateur
vont
8

Par défaut, ViewPager recrée les fragments lorsque vous faites glisser la page. Pour éviter cela, vous pouvez essayer l'une des deux choses suivantes:

1. Dans le onCreate () de vos fragments, appelez setRetainInstance (true).

2. Si le nombre de fragments est fixe et relativement petit, dans votre onCreate (), ajoutez le code suivant:

ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(3);

Si je me souviens bien, la deuxième option est plus prometteuse. Mais je vous exhorte à essayer les deux et à voir lequel d'entre eux fonctionne.

Pankaj Talaviya
la source