我一直在研究使用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行)。
谢谢