How to implement Paginated List View in Android

2019-01-24 22:23发布

问题:

I want to implement Paginated list View in android so when I scroll down to the end, each time more items should add to my list, currently I am fetching 10 items from web service and showing them in a list View, now I want add 10 more Items when user scroll down to the end of the list. Is there any way to do it?

回答1:

EDIT: This one is better: http://p-xr.com/android-tutorial-dynamicaly-load-more-items-to-the-listview-never-ending-list/

-----------------------------------*----------------------

http://benjii.me/2010/08/endless-scrolling-listview-in-android/

public class EndlessScrollListener implements OnScrollListener {

    private int visibleThreshold = 5;
    private int currentPage = 0;
    private int previousTotal = 0;
    private boolean loading = true;

    public EndlessScrollListener() {
    }
    public EndlessScrollListener(int visibleThreshold) {
        this.visibleThreshold = visibleThreshold;
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        if (loading) {
            if (totalItemCount > previousTotal) {
                loading = false;
                previousTotal = totalItemCount;
                currentPage++;
            }
        }
        if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
            // I load the next page of gigs using a background task,
            // but you can call any function here.
            new LoadGigsTask().execute(currentPage + 1);
            loading = true;
        }
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }
}


回答2:

I found a better solution here which actually looks like an enhancements to Waza_Be's solution: https://github.com/thecodepath/android_guides/wiki/Endless-Scrolling-with-AdapterViews (I'm not the author, so credits to https://github.com/thecodepath).

An abstract listener class is implemented with an abstract method that is responsible for loading data, which is excellent for activities to send their specific requests.

I just post the code here, if somehow the code disappears in the wiki.

public abstract class EndlessScrollListener implements OnScrollListener {
    // The minimum amount of items to have below your current scroll position
    // before loading more.
    private int visibleThreshold = 5;
    // The current offset index of data you have loaded
    private int currentPage = 0;
    // The total number of items in the dataset after the last load
    private int previousTotalItemCount = 0;
    // True if we are still waiting for the last set of data to load.
    private boolean loading = true;
    // Sets the starting page index
    private int startingPageIndex = 0;

    public EndlessScrollListener() {
    }

    public EndlessScrollListener(int visibleThreshold) {
        this.visibleThreshold = visibleThreshold;
    }

    public EndlessScrollListener(int visibleThreshold, int startPage) {
        this.visibleThreshold = visibleThreshold;
        this.startingPageIndex = startPage;
        this.currentPage = startPage;
    }

    // This happens many times a second during a scroll, so be wary of the code you place here.
    // We are given a few useful parameters to help us work out if we need to load some more data,
    // but first we check if we are waiting for the previous load to finish.
    @Override
    public void onScroll(AbsListView view,int firstVisibleItem,int visibleItemCount,int totalItemCount) {
        // If the total item count is zero and the previous isn't, assume the
        // list is invalidated and should be reset back to initial state
        if (totalItemCount < previousTotalItemCount) {
            this.currentPage = this.startingPageIndex;
            this.previousTotalItemCount = totalItemCount;
            if (totalItemCount == 0) { this.loading = true; } 
        }

        // If it’s still loading, we check to see if the dataset count has
        // changed, if so we conclude it has finished loading and update the current page
        // number and total item count.
        if (loading && (totalItemCount > previousTotalItemCount)) {
            loading = false;
            previousTotalItemCount = totalItemCount;
            currentPage++;
        }

        // If it isn’t currently loading, we check to see if we have breached
        // the visibleThreshold and need to reload more data.
        // If we do need to reload some more data, we execute onLoadMore to fetch the data.
        if (!loading && (totalItemCount - visibleItemCount)<=(firstVisibleItem + visibleThreshold)) {
            onLoadMore(currentPage + 1, totalItemCount);
            loading = true;
        }
    }

    // Defines the process for actually loading more data based on page
    public abstract void onLoadMore(int page, int totalItemsCount);

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        // Don't take any action on changed
    }
}


回答3:

I think the scroll listener posted by raveN is a good way to go. But the clean way of handling data loading in Android is to use a Loader (CursorLoader or AsyncTaskLoader, depending on where you get your data from).

And surprisingly, I couldn't find any clean way of doing paginations with loaders, so I went ahead and created a base loader that supports it. It's very early stage so feel free to submit pull requests if you find bugs:

https://github.com/nbarraille/paginated_loader

It pretty much adds a loadMore() method to the Loader, and you just have to implement loadInBackground() to load a single page of data, and appendResults() to tell the loader how to combine the results together and that's it.

The sample app uses the endless scroll listener to request more data as soon as the end of the list is reached, more data will be requested.