Une solution consiste à implémenter un OnScrollListeneret à apporter des modifications (comme l'ajout d'éléments, etc.) ListAdapterà un état pratique dans sa onScrollméthode.
Ce qui suit ListActivitymontre une liste d'entiers, commençant par 40, ajoutant des éléments lorsque l'utilisateur fait défiler jusqu'à la fin de la liste.
Vous devez évidemment utiliser des threads séparés pour les actions de longue durée (comme le chargement de données Web) et vous pouvez indiquer la progression dans le dernier élément de la liste (comme le font les applications de marché ou gmail).
hein, cela ne déclencherait-il pas l'augmentation de la taille de l'adaptateur si vous arrêtiez de faire défiler au milieu de l'écran? il ne devrait charger les 10 suivants qu'en atteignant réellement le bas de la liste.
Matthias
9
Je remarque beaucoup d'exemples comme celui-ci en utilisant BaseAdapter. Je voulais mentionner que si vous utilisez une base de données, essayez d'utiliser un SimpleCursorAdapter. Lorsque vous devez ajouter à la liste, mettez à jour votre base de données, obtenez un nouveau curseur et utilisez SimpleCursorAdapter # changeCursor avec notifyDataSetChanged. Aucun sous-classement requis, et il fonctionne mieux qu'un BaseAdapter (encore une fois, uniquement si vous utilisez une base de données).
brack
1
Après avoir appelé notifyDataSetChanged (), il ira en haut de la liste, comment puis-je l'empêcher?
tirage du
2
Une note - J'ai utilisé cette approche, mais je devais ajouter une vérification lorsque visibleCount est 0. Pour chaque liste, j'obtiens un rappel à onScroll où firstVisible, visibleCount et totalCount sont tous à 0, ce qui répond techniquement au conditionnel, mais n'est pas quand je veux charger plus.
Eric Mill
5
Un autre problème avec ce code est que la condition firstVisible + visibleCount >= totalCountest remplie plusieurs fois avec plusieurs appels à l'écouteur. Si la fonction de chargement supplémentaire est une demande Web (très probablement), ajoutez une autre vérification pour savoir si une demande est en cours ou non. D'un autre côté, vérifiez si le totalCount n'est pas égal au nombre total précédent, car nous n'avons pas besoin de plusieurs demandes pour le même nombre d'éléments dans la liste.
Subin Sebastian
94
Je voulais juste apporter une solution que j'ai utilisée pour mon application.
Il est également basé sur l' OnScrollListenerinterface, mais j'ai trouvé qu'il avait de bien meilleures performances de défilement sur les appareils bas de gamme, car aucun des calculs de nombre total / visible n'est effectué pendant les opérations de défilement.
Laissez votre ListFragmentou ListActivitymettre en œuvreOnScrollListener
Ajoutez les méthodes suivantes à cette classe:
@Overridepublicvoid onScroll(AbsListView view,int firstVisibleItem,int visibleItemCount,int totalItemCount){//leave this empty}@Overridepublicvoid onScrollStateChanged(AbsListView listView,int scrollState){if(scrollState == SCROLL_STATE_IDLE){if(listView.getLastVisiblePosition()>= listView.getCount()-1- threshold){
currentPage++;//load more list items:
loadElements(currentPage);}}}
où currentPageest la page de votre source de données qui doit être ajoutée à votre liste, et thresholdest le nombre d'éléments de liste (comptés à partir de la fin) qui devraient, s'ils sont visibles, déclencher le processus de chargement. Si vous définissez thresholdà 0, par exemple, l'utilisateur doit faire défiler jusqu'à la fin de la liste afin de charger plus d' articles.
(facultatif) Comme vous pouvez le voir, la «vérification de chargement supplémentaire» n'est appelée que lorsque l'utilisateur arrête de faire défiler. Pour améliorer la convivialité, vous pouvez gonfler et ajouter un indicateur de chargement à la fin de la liste via listView.addFooterView(yourFooterView). Un exemple pour une telle vue de pied de page:
(facultatif) Enfin, supprimez cet indicateur de chargement en appelant listView.removeFooterView(yourFooterView)s'il n'y a plus d'éléments ou de pages.
J'ai essayé cela mais cela ne fonctionne pas pour ListFragment. Comment peut-il être utilisé dans ListFragment.
zeeshan
Eh bien, je l'utilise ListFragmentégalement sans aucun problème - suivez simplement chacune des étapes ci-dessus et tout ira bien;) Ou pourriez-vous fournir des messages d'erreur?
saschoar
Ce que vous pourriez avoir manqué est expliqué dans cette réponse SO: stackoverflow.com/a/6357957/1478093 -getListView().setOnScrollListener(this)
TBieniek
7
Remarque: l'ajout et la suppression du pied de page dans listview est problématique (le pied de page n'apparaît pas si setAdapter est appelé avant d'ajouter le pied de page), j'ai fini par modifier directement la visibilité de la vue de pied de page sans la supprimer.
dvd
Que faut-il ajouter dans les loadElements (currentPage) ??? Je veux dire est-ce que j'appelle ma AsyncTask ou un thread?
android_developer
20
Vous pouvez détecter la fin de la liste à l'aide de onScrollListener , le code de travail est présenté ci-dessous:
Une autre façon de le faire (à l'intérieur de l'adaptateur) est la suivante:
publicView getView(int pos,View v,ViewGroup p){if(pos==getCount()-1){
addMoreData();//should be asynctask or thread}return view;}
Sachez que cette méthode sera appelée plusieurs fois, vous devez donc ajouter une autre condition pour bloquer plusieurs appels de addMoreData() .
Lorsque vous ajoutez tous les éléments à la liste, veuillez appeler notifyDataSetChanged () dans votre adaptateur pour mettre à jour la vue (elle doit être exécutée sur le thread d'interface utilisateur - runOnUiThread )
Il est inapproprié de faire autre chose que de renvoyer une vue getView. Par exemple, vous n'êtes pas assuré que posl'utilisateur le voit. Il pourrait simplement s'agir de mesures ListView.
Thomas Ahle
Je veux charger plus d'articles après le défilement de 10 articles. mais je remarque que le chargement commence avant que le 10ème élément soit visible signifie sur le 9ème élément. Alors, comment arrêter cela?
Il utilise le Volley HTTP libraryqui rend la mise en réseau pour les applications Android plus facile et, surtout, plus rapide. Volley est disponible via le référentiel AOSP ouvert.
Le code donné montre:
ListView qui est rempli par des requêtes paginées HTTP.
Utilisation de NetworkImageView.
Pagination ListView "sans fin" avec lecture anticipée.
Peut être un peu en retard mais la solution suivante s'est avérée très utile dans mon cas. D'une manière tout ce que vous devez faire est d'ajouter à votre ListView Footeret de créer pour celaaddOnLayoutChangeListener .
ListView listView1 =(ListView) v.findViewById(R.id.dialogsList);// Your listViewView loadMoreView = getActivity().getLayoutInflater().inflate(R.layout.list_load_more,null);// Getting your layout of FooterView, which will always be at the bottom of your listview. E.g. you may place on it the ProgressBar or leave it empty-layout.
listView1.addFooterView(loadMoreView);// Adding your View to your listview ...
loadMoreView.addOnLayoutChangeListener(newView.OnLayoutChangeListener(){@Overridepublicvoid onLayoutChange(View v,int left,int top,int right,int bottom,int oldLeft,int oldTop,int oldRight,int oldBottom){Log.d("Hey!","Your list has reached bottom");}});
Cet événement se déclenche une fois lorsqu'un pied de page devient visible et fonctionne comme un charme.
La clé de ce problème est de détecter l'événement de chargement supplémentaire, de démarrer une demande asynchrone de données, puis de mettre à jour la liste. Un adaptateur avec indicateur de chargement et autres décorateurs est également nécessaire. En fait, le problème est très compliqué dans certains cas d'angle. Une simple OnScrollListenermise en œuvre ne suffit pas, car parfois les éléments ne remplissent pas l'écran.
J'ai écrit un package personnel qui prend en charge une liste sans fin RecyclerViewet fournit également une implémentation de chargeur asynchrone AutoPagerFragmentqui facilite très facilement l'obtention de données à partir d'une source de plusieurs pages. Il peut charger n'importe quelle page de votre choix dans un RecyclerViewévénement personnalisé, pas seulement la page suivante.
Une fois que je l'ai utilisé pour une liste de défilement sans fin, j'ai réalisé que la configuration est très robuste. Je le recommanderais sans hésiter.
J'ai travaillé dans une autre solution très similaire à celle-ci, mais, j'utilise un footerViewpour donner la possibilité à l'utilisateur de télécharger plus d'éléments en cliquant sur le footerView, j'utilise un "menu" qui est affiché au-dessus du ListViewet en bas du vue parent, ce "menu" masque le bas du ListView, donc, lorsque le listViewdéfilement disparaît et que l'état de défilement est inactif, le menu réapparaît, mais lorsque l'utilisateur défile jusqu'à la fin du listView, je "demande" à savoir si footerViews'affiche dans ce cas, le menu n'apparaît pas et l'utilisateur peut voir footerViewpour charger plus de contenu. Voici le code:
Je sais que c'est une vieille question et le monde Android est principalement passé à RecyclerViews, mais pour toute personne intéressée, cette bibliothèque peut être très intéressante.
Il utilise le BaseAdapter utilisé avec le ListView pour détecter quand la liste a été défilée jusqu'au dernier élément ou lorsqu'elle est éloignée du dernier élément.
Il est livré avec un exemple de projet (à peine 100 lignes de code d'activité) qui peut être utilisé pour comprendre rapidement comment cela fonctionne.
le loadMore élément est un bouton ou un autre élément d'interface utilisateur qui peut être cliqué pour extraire plus de données de l'url. Lorsqu'il est placé comme décrit dans le code, l'adaptateur sait exactement quand afficher ce bouton et quand le désactiver. Créez simplement le bouton dans votre xml et placez-le comme indiqué dans le code adaptateur ci-dessus.
Réponses:
Une solution consiste à implémenter un
OnScrollListener
et à apporter des modifications (comme l'ajout d'éléments, etc.)ListAdapter
à un état pratique dans saonScroll
méthode.Ce qui suit
ListActivity
montre une liste d'entiers, commençant par 40, ajoutant des éléments lorsque l'utilisateur fait défiler jusqu'à la fin de la liste.Vous devez évidemment utiliser des threads séparés pour les actions de longue durée (comme le chargement de données Web) et vous pouvez indiquer la progression dans le dernier élément de la liste (comme le font les applications de marché ou gmail).
la source
firstVisible + visibleCount >= totalCount
est remplie plusieurs fois avec plusieurs appels à l'écouteur. Si la fonction de chargement supplémentaire est une demande Web (très probablement), ajoutez une autre vérification pour savoir si une demande est en cours ou non. D'un autre côté, vérifiez si le totalCount n'est pas égal au nombre total précédent, car nous n'avons pas besoin de plusieurs demandes pour le même nombre d'éléments dans la liste.Je voulais juste apporter une solution que j'ai utilisée pour mon application.
Il est également basé sur l'
OnScrollListener
interface, mais j'ai trouvé qu'il avait de bien meilleures performances de défilement sur les appareils bas de gamme, car aucun des calculs de nombre total / visible n'est effectué pendant les opérations de défilement.ListFragment
ouListActivity
mettre en œuvreOnScrollListener
Ajoutez les méthodes suivantes à cette classe:
où
currentPage
est la page de votre source de données qui doit être ajoutée à votre liste, etthreshold
est le nombre d'éléments de liste (comptés à partir de la fin) qui devraient, s'ils sont visibles, déclencher le processus de chargement. Si vous définissezthreshold
à0
, par exemple, l'utilisateur doit faire défiler jusqu'à la fin de la liste afin de charger plus d' articles.(facultatif) Comme vous pouvez le voir, la «vérification de chargement supplémentaire» n'est appelée que lorsque l'utilisateur arrête de faire défiler. Pour améliorer la convivialité, vous pouvez gonfler et ajouter un indicateur de chargement à la fin de la liste via
listView.addFooterView(yourFooterView)
. Un exemple pour une telle vue de pied de page:(facultatif) Enfin, supprimez cet indicateur de chargement en appelant
listView.removeFooterView(yourFooterView)
s'il n'y a plus d'éléments ou de pages.la source
ListFragment
également sans aucun problème - suivez simplement chacune des étapes ci-dessus et tout ira bien;) Ou pourriez-vous fournir des messages d'erreur?getListView().setOnScrollListener(this)
Vous pouvez détecter la fin de la liste à l'aide de onScrollListener , le code de travail est présenté ci-dessous:
Une autre façon de le faire (à l'intérieur de l'adaptateur) est la suivante:
Sachez que cette méthode sera appelée plusieurs fois, vous devez donc ajouter une autre condition pour bloquer plusieurs appels de
addMoreData()
.Lorsque vous ajoutez tous les éléments à la liste, veuillez appeler notifyDataSetChanged () dans votre adaptateur pour mettre à jour la vue (elle doit être exécutée sur le thread d'interface utilisateur - runOnUiThread )
la source
getView
. Par exemple, vous n'êtes pas assuré quepos
l'utilisateur le voit. Il pourrait simplement s'agir de mesures ListView.Chez
Ognyan Bankov GitHub
j'ai trouvé une solution simple et fonctionnelle!Il utilise le
Volley HTTP library
qui rend la mise en réseau pour les applications Android plus facile et, surtout, plus rapide. Volley est disponible via le référentiel AOSP ouvert.Le code donné montre:
Pour une cohérence future, j'ai bifurqué le repo de Bankov .
la source
Voici une solution qui facilite également l'affichage d'une vue de chargement à la fin de ListView pendant le chargement.
Vous pouvez voir les cours ici:
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/helper/ListViewWithLoadingIndicatorHelper.java - Aide à rendre possible l'utilisation du fonctionnalités sans s'étendre à partir de SimpleListViewWithLoadingIndicator.
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/listener/EndlessScrollListener.java - Écouteur qui démarre le chargement des données lorsque l'utilisateur est sur le point d'atteindre le bas du ListView.
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/view/SimpleListViewWithLoadingIndicator.java - The EndlessListView. Vous pouvez utiliser cette classe directement ou l'étendre.
la source
Peut être un peu en retard mais la solution suivante s'est avérée très utile dans mon cas. D'une manière tout ce que vous devez faire est d'ajouter à votre ListView
Footer
et de créer pour celaaddOnLayoutChangeListener
.http://developer.android.com/reference/android/widget/ListView.html#addFooterView(android.view.View)
Par exemple:
Cet événement se déclenche une fois lorsqu'un pied de page devient visible et fonctionne comme un charme.
la source
La clé de ce problème est de détecter l'événement de chargement supplémentaire, de démarrer une demande asynchrone de données, puis de mettre à jour la liste. Un adaptateur avec indicateur de chargement et autres décorateurs est également nécessaire. En fait, le problème est très compliqué dans certains cas d'angle. Une simple
OnScrollListener
mise en œuvre ne suffit pas, car parfois les éléments ne remplissent pas l'écran.J'ai écrit un package personnel qui prend en charge une liste sans fin
RecyclerView
et fournit également une implémentation de chargeur asynchroneAutoPagerFragment
qui facilite très facilement l'obtention de données à partir d'une source de plusieurs pages. Il peut charger n'importe quelle page de votre choix dans unRecyclerView
événement personnalisé, pas seulement la page suivante.Voici l'adresse: https://github.com/SphiaTower/AutoPagerRecyclerManager
la source
Jusqu'à présent, la meilleure solution que j'ai vue est dans la bibliothèque FastAdapter pour les vues de recycleur. Il a un
EndlessRecyclerOnScrollListener
.Voici un exemple d'utilisation: EndlessScrollListActivity
Une fois que je l'ai utilisé pour une liste de défilement sans fin, j'ai réalisé que la configuration est très robuste. Je le recommanderais sans hésiter.
la source
J'ai travaillé dans une autre solution très similaire à celle-ci, mais, j'utilise un
footerView
pour donner la possibilité à l'utilisateur de télécharger plus d'éléments en cliquant sur lefooterView
, j'utilise un "menu" qui est affiché au-dessus duListView
et en bas du vue parent, ce "menu" masque le bas duListView
, donc, lorsque lelistView
défilement disparaît et que l'état de défilement est inactif, le menu réapparaît, mais lorsque l'utilisateur défile jusqu'à la fin dulistView
, je "demande" à savoir sifooterView
s'affiche dans ce cas, le menu n'apparaît pas et l'utilisateur peut voirfooterView
pour charger plus de contenu. Voici le code:Cordialement.
la source
Je sais que c'est une vieille question et le monde Android est principalement passé à RecyclerViews, mais pour toute personne intéressée, cette bibliothèque peut être très intéressante.
Il utilise le BaseAdapter utilisé avec le ListView pour détecter quand la liste a été défilée jusqu'au dernier élément ou lorsqu'elle est éloignée du dernier élément.
Il est livré avec un exemple de projet (à peine 100 lignes de code d'activité) qui peut être utilisé pour comprendre rapidement comment cela fonctionne.
Utilisation simple:
Un adaptateur pour contenir des objets Boy ressemblerait à ceci:
Remarquez comment la méthode getView de BoysAdapter renvoie un appel à la méthode de la superclasse EndlessAdapter
getView
. C'est 100% essentiel.Maintenant, pour créer l'adaptateur, procédez comme suit:
le
loadMore
élément est un bouton ou un autre élément d'interface utilisateur qui peut être cliqué pour extraire plus de données de l'url. Lorsqu'il est placé comme décrit dans le code, l'adaptateur sait exactement quand afficher ce bouton et quand le désactiver. Créez simplement le bouton dans votre xml et placez-le comme indiqué dans le code adaptateur ci-dessus.Prendre plaisir.
la source