Java 无休止地滚动RecyclerView并进行新的api调用以显示新数据

Java 无休止地滚动RecyclerView并进行新的api调用以显示新数据,java,android,android-recyclerview,lazy-loading,retrofit,Java,Android,Android Recyclerview,Lazy Loading,Retrofit,我已经为我的RecyclerView创建了endlessScrollListener。在我的onLoadMore方法中,每当我在页面底部时,我都在进行一个新的api调用。 我需要为我的apiCall方法提供新参数,用于新的api调用以获取新数据。我从第1页开始api调用,第30页-用于项目计数。下一个api调用应该有2,30,下一个3,30,依此类推。 我在考虑做一个循环。但是有谁能建议一个更好的方法吗 public void makeApiCall(int pageNumber, int pa

我已经为我的
RecyclerView
创建了
endlessScrollListener
。在我的
onLoadMore
方法中,每当我在页面底部时,我都在进行一个新的api调用。 我需要为我的
apiCall
方法提供新参数,用于新的api调用以获取新数据。我从第1页开始api调用,第30页-用于项目计数。下一个api调用应该有2,30,下一个3,30,依此类推。 我在考虑做一个循环。但是有谁能建议一个更好的方法吗

public void makeApiCall(int pageNumber, int pageSize) {

    ApiCall.ApiCallRx apiCall = ApiCall.createRx();

    Observable<Response<ApiObject>> observable =
            apiCall.apiItems(ApiKey.apiKey, pageNumber, pageSize);

    observable.observeOn(AndroidSchedulers.mainThread()).
            subscribeOn(Schedulers.io()).
            observeOn(AndroidSchedulers.mainThread()).
            subscribe(new Subscriber<Response<ApiObject>>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {
                    Log.d("MainActivity", "Call Failed"+ e.getMessage());
                }

                @Override
                public void onNext(Response<ApiObject> apiResponse) {
                    callSuccess(apiResponse);
                    Log.d("MainActivity", "Call Success");

                }
            });
}

private void callSuccess(Response<ApiObject> apiResponse) {

    apiItems = apiResponse.body().getProducts();
    objectAdapter = new ObjectAdapter(apiItems);
    recyclerView.setAdapter(objectAdapter);
}

private void setScrollListener(){

    recyclerView.addOnScrollListener(new EndlessRecyclerViewScrollListener(linearLayoutManager) {
        @Override
        public void onLoadMore(int page, int totalItemsCount) {

         makeApiCall(2,30);

        }
    });
}
public void makeApiCall(int pageNumber,int pageSize){
ApiCall.ApiCallRx ApiCall=ApiCall.createRx();
可观察=
apiCall.apitems(ApiKey.ApiKey、页码、页面大小);
observeOn(AndroidSchedulers.mainThread())。
subscribeOn(Schedulers.io())。
observeOn(AndroidSchedulers.mainThread())。
订阅(新订户(){
@凌驾
未完成的公共无效(){
}
@凌驾
公共无效申报人(可丢弃的e){
Log.d(“MainActivity”,“调用失败”+e.getMessage());
}
@凌驾
public void onNext(响应apiResponse){
呼叫成功(apiResponse);
Log.d(“主活动”、“呼叫成功”);
}
});
}
私有void callSuccess(响应apiResponse){
apitems=apiResponse.body().getProducts();
objectAdapter=新的objectAdapter(APItems);
setAdapter(objectAdapter);
}
私有void setScrollListener(){
recyclerView.addOnScrollListener(新EndlessRecyclerViewScrollListener(linearLayoutManager){
@凌驾
public void onLoadMore(整版页面,整版项目目录){
makeApiCall(2,30);
}
});
}

您只需要最后一页的页码就可以知道下一页要取哪一页。 假设传递给onLoadMore的页码是最后一个页码,调用onLoadMore时只需将其递增一,然后获取下一页。 您还应该维护页面请求是否正在进行。如果一个请求正在进行,您不应启动另一个请求。像这样的

if (!requestInProgress){
  pageNumber += 1;
  requestInProgress = true;
  makeApiCall(pageNumber)
}

api请求完成后,将requestInProgress设置为false。您还可以维护一个标志来指示是否已提取所有页面,并使用它来决定是否发出请求。

您可以添加notifyDataSetChanged();在你所谓的成功方法

下面的代码片段将允许您检测视图何时结束

recyclerView.setOnScrollListener(new OnScrollListener(){
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int      visibleItemCount, int totalItemCount)
   {
    if(firstVisibleItem + visibleItemCount >= totalItemCount){
        // End has been reached
    }
}
并且确保你做了一次api调用的逻辑,因为这会多次调用api,因为你在endof列表中。。创建一个全局变量,并在onScroll方法中设置它,然后在onSuccess()中重置它,这样就可以防止多次api调用

如果你想追踪你的页码,其中一种方法就是使用 在OnSuces方法中存储最后一页键 并在onScroll方法中读取它,然后按1和 调用api


希望这对您有所帮助

对于您的评论,是的,我正在使用scroll listener,您只需遵循以下指南即可:

首先,您的
RecyclerView.Adapter
必须如下所示:

public class MyAdapter extends RecyclerView.Adapter{

ArrayList<YourModel> models;
RecyclerView mRecyclerView;
private OnLoadMoreListener mOnLoadMoreListener;
private boolean isLoading;
private int visibleThreshold = 5;
private int lastVisibleItem, totalItemCount;

public void setLoaded() {
    isLoading = false;
}


public void setOnLoadMoreListener(OnLoadMoreListener mOnLoadMoreListener) {
    this.mOnLoadMoreListener = mOnLoadMoreListener;

}

public MyAdapter(ArrayList<YourModel> models,RecyclerView recyclerview){
    this.models=models;
    this.mRecyclerView=recyclerview;

    final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            totalItemCount = linearLayoutManager.getItemCount();
            lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
                if (!isLoading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
                    if (mOnLoadMoreListener != null) {
                        mOnLoadMoreListener.onLoadMore();
                    }
                    isLoading = true;
                }

        }
    });

    }
}
然后在
活动中
声明并将
onScrollListener
添加到适配器中:

MyAdapter myAdapter=new MyAdapter(models,recyclerview);

myAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
        @Override
        public void onLoadMore() {
            if(getNEXT_PAGE()!=0) {
                if (!mIsRefreshing) {
                    //you can add null object for progress view
                    //if you dont want you can disable this 
                    needYouUsers.add(null);
                    needYouAdapter.notifyItemInserted(needYouUsers.size() - 1);
                    mSwipeRefreshLayout.setEnabled(false);
                    makeYourRequest();

                }
            }

        }
    });
然后,您必须在方法中为适配器使用
setLoaded

public void makeYourRequest(){

    //do your all stuff make request etc..
    //finally
     myadapter.setLoaded();
}

我像你一样使用
RecyclerView
。而且它工作得很好。您在这种情况下有问题吗?回收器视图没有问题。但是scroll listener不能按我想要的方式工作。你想要什么,我的recyclerview触发器在我触底时加载更多方法。每次都是!你使用onScrollListener吗?您从哪里加载数据?你打api电话吗?
public void makeYourRequest(){

    //do your all stuff make request etc..
    //finally
     myadapter.setLoaded();
}