content: 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<Integer> 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<List<String>> dataFromNetwork(final int page) {
          return Single.just(true)
                  .delay(2, TimeUnit.SECONDS)
                  .map(value -> {
                      List<String> items = new ArrayList<>();
                      for (int i = 1; i <= 10; i++) {
                          items.add("Item " + (page * 10 + i));
                      }
                      return items;
                  });
      }
  }
  