11 votes

Adaptateur sans fin pour ViewPager

J'ai utilisé L'adaptateur sans fin du CWAC pour obtenir un défilement infini sur les ListViews.

J'aimerais réaliser l'équivalent pour un ViewPager. Malheureusement, PageAdapter et ListAdapter ne partagent pas la même classe de base commune.

Quelle est la meilleure façon de procéder ? Existe-t-il une bibliothèque qui gère déjà cela ?

15voto

CommonsWare Points 402670

Quelle est la meilleure façon de procéder ?

Ajoutez une logique "sans fin" à votre propre implémentation de PagerAdapter . Ou, si vous le souhaitez, essayez de créer une décoration. PagerAdapter , la façon dont les EndlessAdapter décore un Adapter .

Ce dernier point risque d'être délicat, étant donné que PagerAdapter est conçu pour que les pages soient des vues ou des fragments, et la gestion des fragments à l'intérieur de classes telles que FragmentPagerAdapter est un peu effrayant.

Existe-t-il une bibliothèque qui s'occupe déjà de cela ?

Aucune à ma connaissance.

Principalement parce que le cas d'utilisation ne semble pas aussi convaincant. Avec un ListView L'utilisateur peut faire défiler la liste, en parcourant des dizaines ou des centaines de lignes très rapidement. Il semble donc raisonnable d'utiliser "nous sommes arrivés à la fin" comme déclencheur pour charger davantage de données. Avec un ViewPager Cependant, il faut généralement beaucoup plus de temps pour arriver à la fin, en particulier si vous n'utilisez pas la fonction PagerTabStrip ou l'équivalent. Par conséquent, attendre que l'utilisateur arrive à la fin pour commencer à charger des données supplémentaires semble être ennuyeux pour l'utilisateur - vous avez eu tout ce temps pour aller chercher des données supplémentaires, mais vous ne l'avez pas utilisé.

Une autre solution consiste donc à enregistrer une ViewPager.OnPageChangeListener avec votre ViewPager . Quand onPageSelected() et que vous vous considérez comme proche de la fin, lancez un AsyncTask (ou autre) pour aller collecter des données supplémentaires. Le problème est qu'il faut alors mettre à jour les données utilisées par l'application PagerAdapter et appeler notifyDataSetChanged() sur cet adaptateur une fois que les données ont été mises à jour.

6voto

redsnowfox Points 855
@Override
public int getCount() {
    return (Integer.MAX_VALUE);
    //artificially large value for infinite scrolling
}

public int getRealCount(){
//Do something to return the actual number of objects.
}   

@Override
public Object instantiateItem(ViewGroup container, int position) {  
    int virtualPosition = position % getRealCount();
    return instantiateVirtualItem(container, virtualPosition);
}

public Object instantiateVirtualItem(ViewGroup container, final int position) {             
//Do the required part here
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    int virtualPosition = position % getRealCount();
    destroyVirtualItem(container, virtualPosition, object);
}

public void destroyVirtualItem(ViewGroup container, int position, Object object){
    container.removeView((View) object);            
}

Maintenant, la partie la plus importante

pager.setOffscreenPageLimit(10); //your choice
pager.setCurrentItem(Integer.MAX_VALUE/2,false);
//pager is the ViewPager object

PS : J'ai réussi à mettre en œuvre cette solution. Demandez si vous avez encore des doutes.

5voto

Streets Of Boston Points 3978

Vous pouvez peut-être "faire semblant" de la manière suivante :

Vous risquez d'afficher un très grand nombre de pages. Utiliser FragmentStatePagerAdapter classe : https://developer.Android.com/reference/Android/support/v13/app/FragmentStatePagerAdapter.html

Mettre en œuvre la getCount en renvoyant Integer.MAX_VALUE .
Mettre en œuvre la méthode getItemPosition en renvoyant toujours POSITION_NONE .
Mettre en œuvre la getItem comme vous le souhaitez, en renvoyant le fragment approprié.

Ensuite, lorsque l'activité qui héberge le ViewPager démarre, définissez la position initiale du ViewPager sur un nombre très élevé, par exemple viewPager.setCurrentItem(Integer.MAX_VALUE / 2); .

Je n'ai pas essayé moi-même..., YMMV ! :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X