Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Infinite Scrolling Android RecyclerView with RxJava
public static Observable<List<String>> paginatedThings(final Observable<Void> onNextObservable) {
return Observable.create(new Observable.OnSubscribe<List<String>>() {
@Override
public void call(final Subscriber<? super List<String>> subscriber) {
onNextObservable.subscribe(new Observer<Void>() {
int latestPage = -1;
@Override
public void onCompleted() {
subscriber.onCompleted();
}
@Override
public void onError(Throwable e) {
subscriber.onError(e);
}
@Override
public void onNext(Void aVoid) {
latestPage++;
List<String> pageItems = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
pageItems.add("page " + latestPage + " item " + i);
}
subscriber.onNext(pageItems);
}
});
}
});
}
package com.example.rxandroid;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.example.rxandroid.api.RepresentativeApi;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import butterknife.ButterKnife;
import butterknife.InjectView;
import rx.Observable;
import rx.Observer;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.subscriptions.CompositeSubscription;
import timber.log.Timber;
import static rx.android.app.AppObservable.bindActivity;
/**
* Created by Dustin on 2/14/15.
*/
public class ReactiveList extends Activity {
@InjectView(R.id.reactiveList)
RecyclerView reactiveList;
private ReactiveRecyclerAdapter adapter = new ReactiveRecyclerAdapter();
private LinearLayoutManager layoutManager;
private CompositeSubscription subscriptions = new CompositeSubscription();
private List<String> mockItems = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.reactive_list);
ButterKnife.inject(this);
for (int i = 0; i < 100; i++) {
mockItems.add(String.valueOf(i));
}
reactiveList.setHasFixedSize(true);
reactiveList.setAdapter(adapter);
layoutManager = new LinearLayoutManager(this);
reactiveList.setLayoutManager(layoutManager);
adapter.addAll(mockItems);
Observable<Void> pageDetector = Observable.create(new Observable.OnSubscribe<Void>() {
@Override
public void call(final Subscriber<? super Void> subscriber) {
reactiveList.setOnScrollListener(new RecyclerView.OnScrollListener() {
int pastVisibleItems, visibleItemCount, totalItemCount;
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
visibleItemCount = layoutManager.getChildCount();
totalItemCount = layoutManager.getItemCount();
pastVisibleItems = layoutManager.findFirstVisibleItemPosition();
if ((visibleItemCount+pastVisibleItems) >= totalItemCount) {
subscriber.onNext(null);
}
}
});
}
}).debounce(400, TimeUnit.MILLISECONDS);
bindActivity(this, pageDetector);
Observable<List<String>> listItemObservable = RepresentativeApi.paginatedThings(pageDetector);
bindActivity(this, listItemObservable);
subscriptions.add(listItemObservable.observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<List<String>>() {
@Override
public void onCompleted() {
Timber.d("completed");
}
@Override
public void onError(Throwable e) {
Timber.e("error: " + e.getMessage());
}
@Override
public void onNext(List<String> strings) {
adapter.addAll(strings);
}
}));
}
public static class ReactiveRecyclerAdapter extends RecyclerView.Adapter<ReactiveRecyclerAdapter.ReactiveViewHolder> {
private List<String> items = new ArrayList<>();
public void addAll(List<String> moreItems) {
items.addAll(moreItems);
notifyDataSetChanged();
}
@Override
public ReactiveViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1,parent,false);
ReactiveViewHolder vh = new ReactiveViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(ReactiveViewHolder holder, int position) {
String item = items.get(position);
holder.label.setText(item);
}
@Override
public int getItemCount() {
return items.size();
}
public static class ReactiveViewHolder extends RecyclerView.ViewHolder {
TextView label;
public ReactiveViewHolder(View itemView) {
super(itemView);
label = (TextView) itemView.findViewById(android.R.id.text1);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment