如何在 Retrofit 2.0 中处理分页/加载更多内容? [英] How to handle pagination/load more in Retrofit 2.0?

查看:31
本文介绍了如何在 Retrofit 2.0 中处理分页/加载更多内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我还没有找到正确的示例,说明如何在向下滚动 RecyclerView 时让应用从 Retrofit onResponse 加载更多项目.

I haven't found yet the proper examples of how to make an app load more items from Retrofit onResponse while scrolling down the RecyclerView.

这是我如何加载我的拳头 20 项:

Here is how I'm loading my fist 20 items:

List<ModelPartners> model = new ArrayList<>();

Call<ResponsePartners> call = ApiClient.getRetrofit().getPartnerList(params);
call.enqueue(this);

我的 RecyclerView

My RecyclerView

PartnersAdapter adapter = new PartnersAdapter(getContext(), recyclerView, model);
recyclerView.setAdapter(adapter);

这是我的改造 onResponse:

@Override
    public void onResponse(Call<ResponsePartners> call, Response<ResponsePartners> response) {
        if (getActivity() != null && response.isSuccessful()) {
            List<ModelPartners> body = response.body().getData();
            //Rest of the code to add body to my Adapter and notifyDataSetChanged
            }
        }

我的问题是,每次我添加方法以在滚动时加载更多项目时,onResponse 会一直加载到最后一页.即使我已将 set loading 设置为 false.

My Problem is, every time I add the method to load more items on scroll, onResponse keeps loading non-stop till the last page. Even if I have put set loading to false.

有人可以展示如何在 Retrofit 中正确使用分页吗?你在 Retrofit 中使用了哪些库,或者告诉我你是如何按照自己的方式做到的?提前谢谢您

Can someone please show how to properly use pagination in Retrofit? What libraries you used with Retrofit or show me how you did it your way? Thank you in advance

推荐答案

你需要三件事来实现这个,你需要:

You need three things to achieve this, you need:

  1. 您需要一个用于回收器视图的 onscroll 侦听器.
  2. 您需要一种向回收器适配器添加新项目的方法
  3. 您需要调用分页端点

假设你有一个来自服务器的模型

Assuming you have a model like this from the server

public class PagedList<T> {

    private int page = 0;
    private List<T> results = new ArrayList<>();
    private int totalResults = 0;
    private int totalPages = 0;

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public List<T> getResults() {
        return results;
    }

    public void setResults(List<T> results) {
        this.results = results;
    }

    public int getTotalResults() {
        return totalResults;
    }

    public void setTotalResults(int totalResults) {
        this.totalResults = totalResults;
    }

    public int getTotalPages() {
        return totalPages;
    }

    public void setTotalPages(int totalPages) {
        this.totalPages = totalPages;
    }
}

您的 OnScroll 侦听器:-在您的活动中,这就是您所拥有的,因此将第二种方法添加到您的活动中

Your OnScroll Listener: - In your activity this is what you would have, so add the second method to your activity

public void onCreate(Bundle savedInstance) {

    // setup your view components
    // ...

    // get the layout manager
    LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);

    // rest endpoint
    apiEndpoint = retrofit.create(RetrofitEndpoint.class);

    // initialise loading state
    mIsLoading = false;
    mIsLastPage = false;

    // amount of items you want to load per page
    final int pageSize = 20;

    // set up scroll listener
    recyclerView.addOnScrollListener(new  RecyclerView.OnScrollListener() {
            @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            // number of visible items
            int visibleItemCount = layoutManager.getChildCount();
            // number of items in layout
            int totalItemCount = layoutManager.getItemCount();
            // the position of first visible item
            int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();

            boolean isNotLoadingAndNotLastPage = !mIsLoading && !mIsLastPage;
            // flag if number of visible items is at the last
            boolean isAtLastItem = firstVisibleItemPosition + visibleItemCount >= totalItemCount;
            // validate non negative values
            boolean isValidFirstItem = firstVisibleItemPosition >= 0;
            // validate total items are more than possible visible items
            boolean totalIsMoreThanVisible = totalItemCount >= pageSize;
            // flag to know whether to load more
            boolean shouldLoadMore = isValidFirstItem && isAtLastItem && totalIsMoreThanVisible && isNotLoadingAndNotLastPage

            if (shouldLoadMore) loadMoreItems(false);
        }
    });

    // load the first page
    loadMoreItems(true);
}

private void loadMoreItems(boolean isFirstPage) {
    // change loading state
    mIsLoading = true;
    mCurrentPage = mCurrentPage + 1;

    // update recycler adapter with next page
    apiEndpoint.getPagedList(mCurrentPage).enqueue(new Callback<PagedList<Object>>() {
        @Override
        public void onResponse(Call<PagedList<Object>> call, Response<PagedList<Object>> response) {
            PagedList<Object> result = response.body();

            if (result == null) return;
            else if (!isFirstPage) mAdapter.addAll(result.getResults());
            else mAdapter.setList(result.getResults());

            mIsLoading = false;
            mIsLastPage = mCurrentPage == result.getTotalPages();
        }

        @Override
        public void onFailure(Call<PagedList<Object>> call, Throwable t) {
            Log.e("SomeActivity", t.getMessage());
        }
    });
}

回收器适配器:-对于回收器适配器,您只需要添加一个将项目添加到其列表的方法,如下所示

Recycler Adapter: - For the recycler adapter all you need is to add a method that adds items to its list, as below

public class SomeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<Object> list;


    // .. other overridden members

    public void setList(List<Object> list) {
        this.list = list;
        notifyDataSetChanged();
    }

    public void addAll(List<Object> newList) {
        int lastIndex = list.size() - 1;
        list.addAll(newList);
        notifyItemRangeInserted(lastIndex, newList.size());
    }
}

最后是你的改造界面,它占据了页面,如下所示:

Then finally your retrofit interface that takes the page, as below:

interface RetrofitEndpoint {

    @GET("paged/list/endpoint")
    Call<PagedList<Object>> getPagedList(@Query("page") int page);
}

希望有所帮助.

这篇关于如何在 Retrofit 2.0 中处理分页/加载更多内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆