Implementation of onScrollListener to detect the end of scrolling in a ListView

e-cal picture e-cal · Jun 15, 2011 · Viewed 73.2k times · Source

I've a ListView displaying some items. I'd like to perform some operation on the items that are currently displayed in the visible portion of the ListView, depending on how the ListView has been scrolled; thus I thought to implements the OnScrollListener of the ListView. Accordingly to the Android api reference, the onScroll method "will be called after the scroll has completed". This seems to me right what I needed, as once the scroll has completed, I perform my actions on the ListView (the onScroll method returns the index of the first item displayed and the number of items displayed).

But once implemented, I see from the LogCat that the onScroll method is not just fired once the scroll has completed, but is fired for every new item that enters the displaying view, from the beginning to the end of the scrolling. This is not the behavior I expect nor I need. The other method of the listener (onScrollStateChanged), instead, does not provide information about the items currently displayed in the ListView.

So, does anyone know how to use this couple of methods to detect the ending of the scroll and get the information about the displayed items? The misalignment between the api reference and the actual behavior of the method confused me a bit. Thanks in advance.

P.S.: I've seen some similar topics around, but nothing helps me understanding how the whole thing works..!

Answer

e-cal picture e-cal · Jun 17, 2011

In the end I've reached a solution not so much elegant but that worked for me; having figured out that onScroll method is called for every step of the scrolling instead of just being called at the scroll end, and that onScrollStateChanged is actually being called only when scrolling is completed, I do something like this:

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    this.currentFirstVisibleItem = firstVisibleItem;
    this.currentVisibleItemCount = visibleItemCount;
}

public void onScrollStateChanged(AbsListView view, int scrollState) {
    this.currentScrollState = scrollState;
    this.isScrollCompleted();
 }

private void isScrollCompleted() {
    if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE) {
        /*** In this way I detect if there's been a scroll which has completed ***/
        /*** do the work! ***/
    }
}

Practically, everytime the ListView is being scrolled I save the data about the first visible item and the visible item count (onScroll method); when the state of scrolling changes (onScrollStateChanged) I save the state and I call another method which actually understand if there's been a scroll and if it's completed. In this way I also have the data about the visible items that I need. Maybe not clean but works!

Regards