如何在Android中实现分页列表视图

3

我想在安卓中实现分页列表视图,所以当我滚动到底部时,每次都应该添加更多的项目到我的列表中。目前,我从 Web 服务中获取10个项目并在列表视图中显示它们,现在我想在用户滚动到列表末尾时再添加10个项目。有没有办法做到这一点?

3个回答

7
我在这里发现了一个更好的解决方案,它实际上看起来是对Waza_Be的解决方案进行了增强:https://github.com/thecodepath/android_guides/wiki/Endless-Scrolling-with-AdapterViews(我不是作者,所以感谢https://github.com/thecodepath)。
一个抽象的监听器类被实现,并且有一个抽象方法负责加载数据,非常适合活动发送他们的特定请求。
如果代码在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
    }
}

这太棒了。运行非常顺畅。 - Asim
请发送带有适配器的类文件,这对我非常有用。我需要实现分页,我的输入包含页面编号、每页项目数以及URL,我该如何加载服务器数据并在GridView上填充?如何在其中实现OnScrollListener,以便我可以加载剩余数据并附加到现有适配器中,请帮助我。 - Harsha

7
EDIT:这篇更好:http://p-xr.com/android-tutorial-dynamicaly-load-more-items-to-the-listview-never-ending-list/ 无尽滚动的ListView在Android上: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) {
    }
}

代码存在一些问题,它总是在我不滚动列表时执行,可能是因为当列表正在加载时它会自动滚动,你知道这方面的情况吗? - abhishek
LoadGigsTask并没有很好的文档说明,但我相信你能处理好这个问题;-) 你需要将你的数据添加到ListView适配器中,然后使用notifyDataSetChanged。 - Waza_Be

0

我认为raveN发布的滚动监听器是一个不错的选择。 但在Android中处理数据加载的干净方法是使用Loader(取决于您从哪里获取数据,可以使用CursorLoader或AsyncTaskLoader)。

令人惊讶的是,我找不到使用loader进行分页的干净方法,因此我继续创建了一个支持它的基本loader。它还处于早期阶段,如果您发现错误,请随时提交pull request:

https://github.com/nbarraille/paginated_loader

它基本上为Loader添加了一个loadMore()方法,您只需要实现loadInBackground()来加载单个数据页面,以及appendResults()来告诉加载器如何将结果组合在一起即可。
示例应用程序使用无限滚动监听器,在列表末尾到达时请求更多数据,将会请求更多数据。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接