Puis-je savoir si mon ListView est déroulé jusqu'en bas ? J'entends par là que le dernier élément est entièrement visible.
Cela ne permettra pas de détecter si le dernier élément est entièrement visible.
Puis-je savoir si mon ListView est déroulé jusqu'en bas ? J'entends par là que le dernier élément est entièrement visible.
Modifié :
Comme j'ai étudié ce sujet particulier dans l'une de mes applications, je peux écrire une réponse détaillée pour les futurs lecteurs de cette question.
Mettre en œuvre un OnScrollListener
, définissez votre ListView
's onScrollListener
et alors vous devriez être capable de gérer les choses correctement.
Par exemple :
private int preLast;
// Initialization stuff.
yourListView.setOnScrollListener(this);
// ... ... ...
@Override
public void onScroll(AbsListView lw, final int firstVisibleItem,
final int visibleItemCount, final int totalItemCount)
{
switch(lw.getId())
{
case R.id.your_list_id:
// Make your calculation stuff here. You have all your
// needed info from the parameters of this function.
// Sample calculation to determine if the last
// item is fully visible.
final int lastItem = firstVisibleItem + visibleItemCount;
if(lastItem == totalItemCount)
{
if(preLast!=lastItem)
{
//to avoid multiple calls for last item
Log.d("Last", "Last");
preLast = lastItem;
}
}
}
}
Si vous avez des en-têtes ou des pieds de page dans votre liste, vous devez également en tenir compte.
Réponse tardive, mais si vous souhaitez simplement vérifier si votre ListView a défilé jusqu'en bas ou non, sans créer un écouteur d'événement, vous pouvez utiliser cette instruction if :
if (yourListView.getLastVisiblePosition() == yourListView.getAdapter().getCount() -1 &&
yourListView.getChildAt(yourListView.getChildCount() - 1).getBottom() <= yourListView.getHeight())
{
//It is scrolled all the way down here
}
Il vérifie d'abord si la dernière position possible est en vue. Ensuite, il vérifie si le bas du dernier bouton s'aligne sur le bas de la ListView. Vous pouvez faire quelque chose de similaire pour savoir s'il est tout en haut :
if (yourListView.getFirstVisiblePosition() == 0 &&
yourListView.getChildAt(0).getTop() >= 0)
{
//It is scrolled all the way up here
}
Merci. Il faut juste changer ...getChildAt(yourListView.getCount() -1)... en ...getChildAt(yourListView.getChildCount() -1)...
@OferR Pas sûr, mais je pense que getChildCount()
renvoie les vues dans le groupe de vues, ce qui, avec le recyclage des vues, n'est pas le même que le nombre d'éléments dans l'adaptateur. Cependant, puisque ListView descend de AdapterView, vous pouvez utiliser getCount()
directement sur le ListView.
William T. Mallard Votre première phrase est correcte, et c'est exactement ce que nous voulons : La dernière vue affichée dans le groupe. Cela permet de vérifier qu'elle est entièrement visible. (Considérez une ListView avec 20 lignes, mais seulement les 8 dernières sont affichées. Nous voulons obtenir la 8ème vue dans le ViewGroup, pas la 20ème qui n'existe pas).
Cela peut être
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
if (scrollState == 2)
flag = true;
Log.i("Scroll State", "" + scrollState);
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
if ((visibleItemCount == (totalItemCount - firstVisibleItem))
&& flag) {
flag = false;
Log.i("Scroll", "Ended");
}
}
C'était assez pénible de s'occuper du défilement, de détecter quand il est terminé et qu'il est bien en bas de la liste (pas en bas de l'écran visible), et de ne déclencher mon service qu'une seule fois, pour aller chercher des données sur le web. Cependant, cela fonctionne bien maintenant. Le code est le suivant, pour le bénéfice de toute personne confrontée à la même situation.
NOTE : J'ai dû déplacer mon code relatif à l'adaptateur dans onViewCreated au lieu de onCreate et détecter le défilement principalement comme ceci :
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {}
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (getListView().getLastVisiblePosition() == (adapter.getCount() - 1))
if (RideListSimpleCursorAdapter.REACHED_THE_END) {
Log.v(TAG, "Loading more data");
RideListSimpleCursorAdapter.REACHED_THE_END = false;
Intent intent = new Intent(getActivity().getApplicationContext(), FindRideService.class);
getActivity().getApplicationContext().startService(intent);
}
}
Ici, RideListSimpleCursorAdapter.REACHED_THE_END est une variable supplémentaire dans mon SimpleCustomAdapter qui est définie comme ceci :
if (position == getCount() - 1) {
REACHED_THE_END = true;
} else {
REACHED_THE_END = false;
}
Ce n'est que lorsque ces deux conditions sont réunies que cela signifie que je suis effectivement en bas de la liste et que mon service ne sera exécuté qu'une seule fois. Si je n'attrape pas le REACHED_THE_END, même le défilement vers l'arrière déclenche à nouveau le service, tant que le dernier élément est en vue.
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.