代码之家  ›  专栏  ›  技术社区  ›  Marc

recyclerview无限滚动减速

  •  1
  • Marc  · 技术社区  · 7 年前

    我阅读了关于实施的指南 endless scrolling 然后试了一下。以下是我对loadNextDataFromApi的实现:

    public void loadNextDataFromApi(int page, String term) {
        movieService.getMovies(page, term)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<List<Movie>>() {
                    @Override
                    public void onCompleted() {
    
                    }
    
                    @Override
                    public void onError(Throwable e) {
    
                    }
    
                    @Override
                    public void onNext(List<Movie> currentPageMovies) {
                        int start = allMovies.size();
                        allMovies.addAll(currentPageMovies);
                        adapter.notifyItemRangeInserted(start, currentPageMovies.size());
                    }
                });
    }
    

    为了使分页系统继续可靠地工作,您应该确保在将新项目添加到列表之前清除项目的适配器(或在清除阵列后通知适配器)

    但将上面的onNext实现更改为这一点打破了无尽的滚动:

                @Override
                public void onNext(List<Movie> currentPageMovies) {
                    allMovies.clear();
                    adapter.notifyDataSetChanged();
                    int start = allMovies.size();
                    allMovies.addAll(currentPageMovies);
                    adapter.notifyItemRangeInserted(start, currentPageMovies.size());
                }
    

    您不需要将列表的前几页保留在allMovies列表中以进行滚动备份吗?同时,根据页数的不同,使用无休止的卷轴进行操作可能会导致OOM

    1 回复  |  直到 7 年前
        1
  •  0
  •   Khemraj Sharma    7 年前

    我一直在使用api调用进行无休止的滚动,因此我可以与您共享我的代码,因为我发现我的列表做得很好。

    首先使用此方法获取recyclerview已到达最后位置。

    public void setRecyclerViewLastPositionListner(RecyclerView rv, final LinearLayoutManager mLayoutManager, final OnLastPositionReached onLastPositionReached) {
        rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                    userScrolled = true;
                }
            }
    
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
    
                super.onScrolled(recyclerView, dx, dy);
                // Here get the child count, item count and visibleitems
                // from layout manager
    
                visibleItemCount = mLayoutManager.getChildCount();
                totalItemCount = mLayoutManager.getItemCount();
                pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();
    
                // Now check if userScrolled is true and also check if
                // the item is end then update recycler view and set
                // userScrolled to false
                if (userScrolled && (visibleItemCount + pastVisiblesItems) == totalItemCount) {
                    userScrolled = false;
                    if (onLastPositionReached != null) onLastPositionReached.onReached();
                }
            }
        });
    }
    

    这里使用接口

    public interface OnLastPositionReached {
        void onReached();
    }
    

    像这样使用它

    UtilitiesV2.getInstance().setRecyclerViewLastPositionListner(yourRecyclerView, mLayoutManager, new UtilitiesV2.OnLastPositionReached() {
                @Override
                public void onReached() {
                    callEBookApi();
                }
            });
    

    这些变量保持下一个api调用的开始位置。

      long start = 0;
        private int lastReceivedListSize = 0;
          int DEFAULT_LIMIT = 20;
    

    考虑在此处调用api。

     private void callEBookApi() {
            start = booksAdapter.getItemCount();
            if (start != 0 & lastReceivedListSize < DEFAULT_LIMIT)
                return;
            BeanLimit beanLimit = new BeanLimit();
            beanLimit.setLimit(DEFAULT_LIMIT);
            beanLimit.setStartpoint(start);
            showProgressBar();
            try {
                callWebServicePost(Interactor.RequestCode_getEbooks, Interactor.Tag_getEbooks, Interactor.Method_getEbooks, new JSONObject(new Gson().toJson(beanLimit)), false, new OnResponseListener() {
                    @Override
                    public void onSuccess(int requestCode, Response responsePacket) {
    
                        hideProgressBar();
    
                            ArrayList<BookBean> list = responsePacket.getResponsePacket().getBooksList();
                            lastReceivedListSize = list.size();
                            updateListData(list);
    
                    }
    
                    @Override
                    public void onError(int requestCode, ErrorType errorType) {
                        FragmentEbooks.super.onError(requestCode, errorType);
                        hideProgressBar();
                        UtilProject.getInstance().showNothingToDisplayLayout(FragmentEbooks.this);
                    }
                });
            } catch (JSONException e) {
                e.printStackTrace();
                hideProgressBar();
            }
        }
    
    
    
    
        private void updateListData(ArrayList<BookBean> list) {
            if (list == null) listBooks = new ArrayList<>();
            booksAdapter.insertItemsInList(list);
            if (booksAdapter.getList().size() != 0) {
               // UtilProject.getInstance().hideNothingToDisplayAndProgressBar(this);   /*here you show placeholder if list empty*/
            } else {
               // UtilProject.getInstance().showNothingToDisplayLayout(this);
            }
        }
    
    
    
    
    
        public void insertItemsInList(ArrayList<InvitationBean> myList) {
            if (list == null) list = new ArrayList<>();
            int lastIndex = list.size();
            list.addAll(myList);
            notifyItemRangeInserted(lastIndex, myList.size());  /*use this line for smooth scrolling if you use notifyDataSetChanged it will load all data again*/
    //        notifyDataSetChanged();
        }
    

    希望这对你有帮助。