Android RecyclerView - Endless Pagination [Infinite Scroll]

December 1, 2017 Oclemy Android RecyclerView 5 minutes, 30 seconds

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.

Comments