Comment puis-je créer une liste où lorsque vous atteignez la fin de la liste, je suis informé si je peux charger plus d'articles?
Réponses
Trop de publicités?Une solution est de mettre en œuvre un OnScrollListener
et de faire des changements (comme l'ajout d'éléments, etc.) à l' ListAdapter
à une pratique de l'état dans ses onScroll
méthode.
La suite de ListActivity
montre une liste d'entiers, à commencer par 40, ajout d'éléments lorsque l'utilisateur fait défiler à la fin de la liste.
public class Test extends ListActivity implements OnScrollListener {
Aleph0 adapter = new Aleph0();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(adapter);
getListView().setOnScrollListener(this);
}
public void onScroll(AbsListView view,
int firstVisible, int visibleCount, int totalCount) {
boolean loadMore = /* maybe add a padding */
firstVisible + visibleCount >= totalCount;
if(loadMore) {
adapter.count += visibleCount; // or any other amount
adapter.notifyDataSetChanged();
}
}
public void onScrollStateChanged(AbsListView v, int s) { }
class Aleph0 extends BaseAdapter {
int count = 40; /* starting amount */
public int getCount() { return count; }
public Object getItem(int pos) { return pos; }
public long getItemId(int pos) { return pos; }
public View getView(int pos, View v, ViewGroup p) {
TextView view = new TextView(Test.this);
view.setText("entry " + pos);
return view;
}
}
}
Vous devez évidemment utiliser des threads séparés pendant de longues actions en cours d'exécution (comme le chargement web de données) et pourrait vouloir indiquer les progrès accomplis dans le dernier élément de la liste (comme le marché ou gmail apps).
Juste voulu contribuer à une solution que j'ai utilisé pour mon application.
Il est également basé sur l' OnScrollListener
interface, mais je l'ai trouvé un peu mieux les performances de défilement sur le bas de gamme des appareils, car aucun de visible/nombre total calculs sont effectués pendant le défilement des opérations.
- Laissez votre
ListFragment
ouListActivity
œuvreOnScrollListener
-
Ajoutez les méthodes suivantes à la classe:
@Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { //leave this empty } @Override public void 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ù
currentPage
est la page de votre source de données qui devrait être ajouté à votre liste, etthreshold
est le nombre d'éléments de la liste (comptées à partir de la fin) qui devrait, si elle est visible, déclencher le processus de chargement. Si vous définissezthreshold
de0
, par exemple, l'utilisateur doit faire défiler jusqu'à la fin de la liste dans l'ordre de charger plus d'articles. -
(facultatif) Comme vous pouvez le voir, la "charge-plus de vérifier" n'est appelée lorsque l'utilisateur cesse de défiler. Pour améliorer la facilité d'utilisation, vous pouvez gonfler et ajouter un indicateur de chargement à la fin de la liste via
listView.addFooterView(yourFooterView)
. Un exemple pour un tel pied de page vue:<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/footer_layout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="10dp" > <ProgressBar android:id="@+id/progressBar1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_gravity="center_vertical" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@+id/progressBar1" android:padding="5dp" android:text="@string/loading_text" /> </RelativeLayout>
(facultatif) Enfin, supprimez l'indicateur de chargement en appelant
listView.removeFooterView(yourFooterView)
si il n'y a pas plus d'articles ou de pages.
Vous pouvez détecter la fin de la liste avec l'aide de onScrollListener, code de travail est présenté ci-dessous:
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (view.getAdapter() != null && ((firstVisibleItem + visibleItemCount) >= totalItemCount) && totalItemCount != mPrevTotalItemCount) {
Log.v(TAG, "onListEnd, extending list");
mPrevTotalItemCount = totalItemCount;
mAdapter.addMoreData();
}
}
Une autre façon de le faire (à l'intérieur de l'adaptateur) est comme suit:
public View 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 de nombreuses fois, vous devez ajouter une autre condition pour bloquer les appels multiples de addMoreData()
.
Lorsque vous ajoutez des éléments à la liste, veuillez appeler notifyDataSetChanged() à l'intérieur de la vôtre adaptateur pour mettre à jour la Vue (il doit être exécuté sur le thread d'INTERFACE utilisateur - runOnUiThread)
Voici une solution qui permet également de montrer un chargement de vue à la fin de la liste alors que c'est le chargement.
Vous pouvez voir les classes ici:
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/helper/ListViewWithLoadingIndicatorHelper.java - De l'aide pour permettre d'utiliser les fonctionnalités sans s'étendant à partir de SimpleListViewWithLoadingIndicator.
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/listener/EndlessScrollListener.java - Auditeur qui commence le chargement de données lorsque l'utilisateur est sur le point d'atteindre le bas de la liste.
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/view/SimpleListViewWithLoadingIndicator.java - Le EndlessListView. Vous pouvez utiliser cette classe directement ou étendre.
J'ai travaillé dans une autre solution, très semblable à cela, mais, je suis en utilisant un footerView de donner la possibilité à l'utilisateur de télécharger plus d'éléments en cliquant sur le footerView, je suis à l'aide d'un "menu" qui est affiché au dessus de la ListView et en bas de la vue parent, cette "menu" cache le bas de la liste, de sorte que, lorsque la liste est de défilement, le menu disparaît et quand de défilement de l'état est inactif, le menu s'affiche de nouveau, mais lorsque l'utilisateur fait défiler à la fin de la liste, J' "demander" pour savoir si le footerView est montré dans ce cas, le menu ne s'affiche pas et l'utilisateur peut voir les footerView pour charger plus de contenu. Voici le code:
Ce qui concerne.
listView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
if(scrollState == SCROLL_STATE_IDLE)
{
if(footerView.isShown())
bottomView.setVisibility(LinearLayout.INVISIBLE);
else
bottomView.setVisibility(LinearLayout.VISIBLE);
}else{
bottomView.setVisibility(LinearLayout.INVISIBLE);
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
});