Android RecyclerView - Endless Pagination [Infinite Scroll]

android pagination

An infinite/endless pagination example with a RecyclerView.

If we reach the end of a given page,the next page gets automatically loaded.While its being loaded we display a progressbar.We are autogenerating data using handles to simulate download of fresh data.

Overview

  • Infinite/Endless pagination in a RecyclerView.
  • RecyclerView consists of CardViews with text.
  • If we reach the end of a page,we automatically load more data.
  • While loading data we display a progressbar.
  • We simulate downloading of data using handlers.
  • We also implement Swipe to refresh.
  • When we refresh we are taken back to the first page.
  • The next page gets loaded in advance.
  • We are using PullLoadView library.

     

Classes

STEP 1 : Our Build.Gradle

  • Lets fetch the library pulltoloadview from jcenter.
  • Moreover we are using a RecyclerView and CardView,so add design support libraries as well as cardview dependency.

 

apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "25.0.1"

    defaultConfig {
        applicationId "com.tutorials.hp.rvinfinitepagination"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.2.1'
    compile 'com.android.support:design:24.2.1'
    compile 'com.android.support:cardview-v7:24.2.1'
    compile 'com.github.tosslife:pullloadview:1.1.0'
}

STEP 2.  Layout - ContentMainxml

  • Inside our ContentMain.xml we have the pullloadview layout.

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.tutorials.hp.rvinfinitepagination.MainActivity"
    tools:showIn="@layout/activity_main">

    <com.srx.widget.PullToLoadView
        android:id="@+id/pullToLoadView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</RelativeLayout>

SETP 3 : Our Spacecraft class

  • Our model class,our data object.
  • Spacecraft with properties like name and propellant.

 

package com.tutorials.hp.rvinfinitepagination.mData;

public class Spaceship {
    private String name;

    public Spaceship(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }
}

STEP 4 : Our RecyclerView Adapter and ViewHolder classes

  • Our ViewHolder class shall hold our views like TextView inside our CardView for recycliing.
  • We shall inflate our model.xml layout in our recyclerview.adapter subclass.

 

package com.tutorials.hp.rvinfinitepagination.mRecycler;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.tutorials.hp.rvinfinitepagination.R;
import com.tutorials.hp.rvinfinitepagination.mData.Spaceship;

import java.util.ArrayList;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> {

    Context c;
    ArrayList<Spaceship> spaceships;

    /*
    CONSTRUCTOR
     */
    public MyAdapter(Context c, ArrayList<Spaceship> spaceships) {
        this.c = c;
        this.spaceships = spaceships;
    }

    //INITIALIE VH
    @Override
    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.model,parent,false);
        MyHolder holder=new MyHolder(v);
        return holder;
    }

    //BIND DATA
    @Override
    public void onBindViewHolder(MyHolder holder, int position) {
        holder.nametxt.setText(spaceships.get(position).toString());

    }

    /*
    TOTAL ITEMS
     */
    @Override
    public int getItemCount() {
        return spaceships.size();

    }

    /*
    ADD DATA TO ADAPTER
     */
    public void add(Spaceship s) {
        spaceships.add(s);
        notifyDataSetChanged();
    }

    /*
    CLEAR DATA FROM ADAPTER
     */
    public void clear() {
        spaceships.clear();
        notifyDataSetChanged();
    }

    /*
    VIEW HOLDER CLASS
     */
    class MyHolder extends RecyclerView.ViewHolder {

        TextView nametxt;

        public MyHolder(View itemView) {
            super(itemView);

            this.nametxt= (TextView) itemView.findViewById(R.id.nameTxt);

        }
    }

}

STEP 5 : Our Paginator class

  • To page our data.
  • We use Handlers to simulate downloading of data updates as the user scrolls.
  • The user can scroll infinitely/endlessly as in this case we generate dummy data as he scrolls.
  • We paging/paginating with five items per page.
  • Our app is also supporting pull/swipe to refresh.
  • If you pull down/swipe down,we refresh and take you to the first page.

 

package com.tutorials.hp.rvinfinitepagination.mData;

import android.content.Context;
import android.os.Handler;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import com.srx.widget.PullCallback;
import com.srx.widget.PullToLoadView;
import com.tutorials.hp.rvinfinitepagination.mRecycler.MyAdapter;

import java.util.ArrayList;

public class Paginator {

    Context c;
    private PullToLoadView pullToLoadView;
    RecyclerView rv;
    private MyAdapter adapter;
    private boolean isLoading = false;
    private boolean hasLoadedAll = false;
    private int nextPage;

    public Paginator(Context c, PullToLoadView pullToLoadView) {
        this.c = c;
        this.pullToLoadView = pullToLoadView;

        //RECYCLERVIEW
        RecyclerView rv=pullToLoadView.getRecyclerView();
        rv.setLayoutManager(new LinearLayoutManager(c, LinearLayoutManager.VERTICAL,false));

        adapter=new MyAdapter(c,new ArrayList<Spaceship>());
        rv.setAdapter(adapter);

        initializePaginator();
    }

/*
PAGE DATA
 */
    public void initializePaginator()
    {
        pullToLoadView.isLoadMoreEnabled(true);
        pullToLoadView.setPullCallback(new PullCallback() {

            //LOAD MORE DATA
            @Override
            public void onLoadMore() {
                loadData(nextPage);
            }

            //REFRESH AND TAKE US TO FIRST PAGE
            @Override
            public void onRefresh() {
                adapter.clear();
                hasLoadedAll=false;
                loadData(1);
            }

            //IS LOADING
            @Override
            public boolean isLoading() {
                return isLoading;
            }

            //CURRENT PAGE LOADED
            @Override
            public boolean hasLoadedAllItems() {
                return hasLoadedAll;
            }
        });

        pullToLoadView.initLoad();
    }

/*
 LOAD MORE DATA
 SIMULATE USING HANDLERS
 */
    public void loadData(final int page)
    {
       isLoading=true;
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {

                //ADD CURRENT PAGE'S DATA
                for (int i=0;i<=5;i++)
                {
                    adapter.add(new Spaceship("Spaceship : "+String.valueOf(i)+" in Page : "+String.valueOf(page)));
                }

                //UPDATE PROPETIES
                pullToLoadView.setComplete();
                isLoading=false;
                nextPage=page+1;

            }
        },3000);
    }

}

STEP 6 : Our MainActivity class

  • Why don't we initialize all our views like recyclerview here? Well lets do so.
  • Then set its layout manager and adapter.

 

package com.tutorials.hp.rvinfinitepagination;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;

import com.srx.widget.PullToLoadView;
import com.tutorials.hp.rvinfinitepagination.mData.Paginator;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        PullToLoadView pullToLoadView= (PullToLoadView) findViewById(R.id.pullToLoadView);
        new Paginator(this,pullToLoadView).initializePaginator();

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

}

 

How to Download and  Run.

 

  • Download the project above.
  • You'll get a zipped file,extract it.
  • Open the Android Studio.
  • Now close, already open project
  • From the Menu bar click on File >New> Import Project
  • Now Choose a Destination Folder, from where you want to import project.
  • Choose an Android Project.
  • Now Click on “OK“.
  • Done, your Project importing start.

More Resources

Resource Link
GitHub Browse Browse
GitHub Download Link Download

Best Regards, Oclemy.

How do You Feel after reading this?

According to scientists, we humans have 8 primary innate emotions: joy, acceptance, fear, surprise, sadness, disgust, anger, and anticipation. Feel free to tell us how you feel about this article using these emotes or via the comment section. This feedback helps us gauge our progress.

Help me Grow.

I set myself some growth ambitions I desire to achieve by this year's end regarding this website and my youtube channel. Am halfway. Help me reach them by:




Recommendations


What do You Think


Previous Post Next Post