如何在 Retrofit 2.0 中处理分页/加载更多内容?

Ali*_*ukh 3 pagination android gson retrofit

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

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

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

Call<ResponsePartners> call = ApiClient.getRetrofit().getPartnerList(params);
call.enqueue(this);
Run Code Online (Sandbox Code Playgroud)

我的 RecyclerView

PartnersAdapter adapter = new PartnersAdapter(getContext(), recyclerView, model);
recyclerView.setAdapter(adapter);
Run Code Online (Sandbox Code Playgroud)

这是我的改造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
            }
        }
Run Code Online (Sandbox Code Playgroud)

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

有人可以展示如何在 Retrofit 中正确使用分页吗?你在 Retrofit 中使用了哪些库,或者告诉我你是如何做到的?先感谢您

Ebi*_*eze 11

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

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

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

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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());
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

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

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

然后最后你的改造界面需要页面,如下所示:

interface RetrofitEndpoint {

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

希望有帮助。