package com.rxjava2.android.samples.ui.pagination; import android.os.Bundle; import android.view.View; import android.widget.ProgressBar; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.rxjava2.android.samples.R; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import io.reactivex.Single; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.Disposable; import io.reactivex.processors.PublishProcessor; import io.reactivex.schedulers.Schedulers; /** * Created by amitshekhar on 15/03/17. */ public class PaginationActivity extends AppCompatActivity { public static final String TAG = PaginationActivity.class.getSimpleName(); private CompositeDisposable compositeDisposable = new CompositeDisposable(); private PublishProcessor paginator = PublishProcessor.create(); private PaginationAdapter paginationAdapter; private RecyclerView recyclerView; private ProgressBar progressBar; private boolean loading = false; private int pageNumber = 1; private final int VISIBLE_THRESHOLD = 1; private int lastVisibleItem, totalItemCount; private LinearLayoutManager layoutManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_pagination); recyclerView = findViewById(R.id.recyclerView); progressBar = findViewById(R.id.progressBar); layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(RecyclerView.VERTICAL); recyclerView.setLayoutManager(layoutManager); paginationAdapter = new PaginationAdapter(); recyclerView.setAdapter(paginationAdapter); setUpLoadMoreListener(); subscribeForData(); } @Override protected void onDestroy() { super.onDestroy(); compositeDisposable.clear(); } /** * setting listener to get callback for load more */ private void setUpLoadMoreListener() { recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); totalItemCount = layoutManager.getItemCount(); lastVisibleItem = layoutManager .findLastVisibleItemPosition(); if (!loading && totalItemCount <= (lastVisibleItem + VISIBLE_THRESHOLD)) { pageNumber++; paginator.onNext(pageNumber); loading = true; } } }); } /** * subscribing for data */ private void subscribeForData() { Disposable disposable = paginator .onBackpressureDrop() .doOnNext(page -> { loading = true; progressBar.setVisibility(View.VISIBLE); }) .concatMapSingle(page -> dataFromNetwork(page) .subscribeOn(Schedulers.io()) .doOnError(throwable -> { // handle error }) // continue emission in case of error also .onErrorReturn(throwable -> new ArrayList<>())) .observeOn(AndroidSchedulers.mainThread()) .subscribe(items -> { paginationAdapter.addItems(items); paginationAdapter.notifyDataSetChanged(); loading = false; progressBar.setVisibility(View.INVISIBLE); }); compositeDisposable.add(disposable); paginator.onNext(pageNumber); } /** * Simulation of network data */ private Single> dataFromNetwork(final int page) { return Single.just(true) .delay(2, TimeUnit.SECONDS) .map(value -> { List items = new ArrayList<>(); for (int i = 1; i <= 10; i++) { items.add("Item " + (page * 10 + i)); } return items; }); } }