recyclerview无休止的滚动减速

时间:2017-11-11 06:18:34

标签: android out-of-memory

我阅读了有关实施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());
                }
            });
}

allMovies保存给定搜索的所有电影。这最初工作正常,但滚动最终加载速度较慢,从平滑滚动到一次3个电影(为每个请求指定的数字)。我认为这是因为列表增长并占用了越来越多的内存。文章提到,

  

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

但是将上面的onNext实现改为this会打破无限滚动:

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

您是否需要在allMovies列表中保留List的前一页以便向上滚动?同时使用无限滚动可以根据页数导致OOM

1 个答案:

答案 0 :(得分:0)

我已经使用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();
    }

希望这会对你有所帮助。