RecyclerView无尽滚动不滚动

时间:2018-08-25 19:40:47

标签: android android-recyclerview retrofit2 infinite-scroll

我一直在研究使用RecyclerView进行无尽的滚动。 我对服务的定义如下:

@GET("discover/movie")
Observable<MovieResponse> discoverMovies(@Query("page") int page);

如您所见,它采用类型为int的查询参数。以下是我的片段类,我在其中使用Retrofit2 Observable发出服务请求。

public class MoviesFragment extends Fragment {

    private static final int COLUMN_COUNT = 2;
    private MoviesGridAdapter adapter;
    private MovieService service;
    private CompositeDisposable disposable = new CompositeDisposable();
    private int pageNum = 1;
    private GridLayoutManager layoutManager;
    private RecyclerView recyclerView;

    public MoviesFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        service = ServiceFactory.createService(MovieService.class);
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.movies_fragment_container, container, false);
        recyclerView = view.findViewById(R.id.movies_recycler_view);
        pageLoader = view.findViewById(R.id.movies_page_loader);
        layoutManager = new GridLayoutManager(getContext(), COLUMN_COUNT);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());

        loadmore();
        return view;
    }

    private void loadmore() {
        recyclerView.addOnScrollListener(new EndlessRecyclerView(layoutManager) {
            @Override
            public void onLoadMore(int totalItemsCount, RecyclerView view) {
                pageNum++;
                parseMovie(pageNum);
            }
        });
    }

    private void parseMovie(int page) {
        service.discoverMovies(page)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(new DisposableObserver<MovieResponse>() {
                               @Override
                               public void onNext(MovieResponse moviesResponse) {
                                   adapter = new MoviesGridAdapter(getContext(), moviesResponse);
                                   recyclerView.setAdapter(adapter);
                                   adapter.notifyDataSetChanged();
                               }

                               @Override
                               public void onError(Throwable e) {
                                   errorDialog();
                               }

                               @Override
                               public void onComplete() {

                               }
                           }
                );
    }

    @Override
    public void onResume() {
        super.onResume();
        moviesSubscription(1);
    }

}

当我尝试滚动时,它恰巧加载第二页(或第二页)。但是我陷入了第二页。我无法从那里向上或向下滚动。我知道我在某处丢失了一块,或者我做错了。

public abstract class EndlessRecyclerView extends RecyclerView.OnScrollListener {
    private int visibleThreshold = 2;
    private int previousTotalItemCount = 0;
    private boolean loading = true;

    private RecyclerView.LayoutManager mLayoutManager;

    public EndlessRecyclerView(LinearLayoutManager layoutManager) {
        this.mLayoutManager = layoutManager;
    }

    public EndlessRecyclerView(GridLayoutManager layoutManager) {
        this.mLayoutManager = layoutManager;
        visibleThreshold = visibleThreshold * layoutManager.getSpanCount();
    }

    public EndlessRecyclerView(StaggeredGridLayoutManager layoutManager) {
        this.mLayoutManager = layoutManager;
        visibleThreshold = visibleThreshold * layoutManager.getSpanCount();
    }

    public int getLastVisibleItem(int[] lastVisibleItemPositions) {
        int maxSize = 0;
        for (int i = 0; i < lastVisibleItemPositions.length; i++) {
            if (i == 0) {
                maxSize = lastVisibleItemPositions[i];
            } else if (lastVisibleItemPositions[i] > maxSize) {
                maxSize = lastVisibleItemPositions[i];
            }
        }
        return maxSize;
    }

    @Override
    public void onScrolled(RecyclerView view, int dx, int dy) {
        int totalItemCount = mLayoutManager.getItemCount();
        int lastVisibleItemPosition = 0;

        if (mLayoutManager instanceof StaggeredGridLayoutManager) {
            int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(null);
            lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions);
        } else if (mLayoutManager instanceof GridLayoutManager) {
            lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition();
        } else if (mLayoutManager instanceof LinearLayoutManager) {
            lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition();
        }

        if (totalItemCount < previousTotalItemCount) {
            this.previousTotalItemCount = totalItemCount;
            if (totalItemCount == 0) {
                this.loading = true;
            }
        }

        if (loading && (totalItemCount > previousTotalItemCount)) {
            loading = false;
            previousTotalItemCount = totalItemCount;
        if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount
                && view.getAdapter().getItemCount() > visibleThreshold) {
            onLoadMore(totalItemCount, view);
            loading = true;
        }
    }

    public void resetState() {
        this.previousTotalItemCount = 0;
        this.loading = true;
    }

    public boolean isLoading() {
        return loading;
    }

    public void setLoading(boolean loading) {
        this.loading = loading;
    }

    public int getFirstCompletelyVisibleItemPosition() {
        return ((GridLayoutManager) mLayoutManager).findFirstCompletelyVisibleItemPosition();
    }

    public abstract void onLoadMore(int totalItemsCount, RecyclerView view);
}

那是我目前在项目中拥有的无休止的回收者视图侦听器。

问题:我如何使用RecyclerView进行分页?

我也尝试过使用flatMap,但我也无法实现。我很高兴得到您有关如何使用flatMap或RecyclerView的addOnScrollListener实现无穷滚动的输入。我希望向上滚动到最大页数(使用Inter.MAX_VALUE行)。

谢谢

1 个答案:

答案 0 :(得分:0)

节省您的时间,并使用此库实现分页

https://github.com/MarkoMilos/Paginate