How to implement load more recyclerview in android

Issue

I want to implement load more in Recyclerview. Here is the code. The code is from github. https://gist.github.com/ssinss/e06f12ef66c51252563e

MainActivity code:

package com.example.tatson.bila;
import android.app.ProgressDialog;
import android.os.AsyncTask;

import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import com.example.tatson.bila.CardAdapter;
import com.example.tatson.bila.Config;
import com.example.tatson.bila.SuperHeroes;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Text;

import java.util.ArrayList;
import java.util.List;


public class MainActivity extends AppCompatActivity  implements SwipeRefreshLayout.OnRefreshListener{

    SwipeRefreshLayout swipeLayout;

    LinearLayoutManager mLayoutManager;

    // initially offset will be 0, later will be updated while parsing the json
    private int offSet  0;

    private int previousTotal  0;


    int pastVisiblesItems, visibleItemCount, totalItemCount;
    private boolean loading  true; // True if we are still waiting for the last set of data to load.
    private int visibleThreshold  5; // The minimum amount of items to have below your current scroll position before loading more.
    int firstVisibleItem;
    private int current_page  1;
    //Creating a List of superheroes
    private List<SuperHeroes> listSuperHeroes;

    //Creating Views
    private RecyclerView recyclerView;
    private RecyclerView.LayoutManager layoutManager;
    private RecyclerView.Adapter adapter;
    public String Img;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Initializing Views
        recyclerView  (RecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true);
        layoutManager  new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        LinearLayoutManager linearLayoutManager  new LinearLayoutManager(this);

        //Initializing our superheroes list
        listSuperHeroes  new ArrayList<>();


        mLayoutManager  new LinearLayoutManager(this);
        recyclerView.setLayoutManager(mLayoutManager);

        swipeLayout  (SwipeRefreshLayout) findViewById(R.id.swipe_container);
        swipeLayout.setOnRefreshListener(this);
        swipeLayout.setColorSchemeResources(android.R.color.holo_blue_bright,
                android.R.color.holo_green_light,
                android.R.color.holo_orange_light,
                android.R.color.holo_red_light);

        swipeLayout.post(new Runnable() {
                             @Override
                             public void run() {
                                 swipeLayout.setRefreshing(true);

                                 getData();
                             }
                         }
        );

        recyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(linearLayoutManager) {
            @Override
            public void onLoadMore(int current_page) {

               Log.d("End","Sucess");

            }
        });

    }


    //This method will get data from the web api
    private void getData(){
        //Showing a progress dialog
        // final ProgressDialog loading  ProgressDialog.show(this,"Loading Data", "Please wait...",false,false);

// appending offset to url
        String url  Config.DATA_URL;
        String url1  url + offSet;
        //Creating a json array request
        JsonArrayRequest jsonArrayRequest  new JsonArrayRequest(url1,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        //Dismissing progress dialog
                        // loading.dismiss();

                        //calling method to parse json array
                        parseData(response);
                        adapter.notifyDataSetChanged();
                        // stopping swipe refresh
                        swipeLayout.setRefreshing(false);
                    }

                },

                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {

                    }
                });



        //Creating request queue
        RequestQueue requestQueue  Volley.newRequestQueue(this);

        //Adding request to the queue
        requestQueue.add(jsonArrayRequest);


    }

    //This method will parse json data
    private void parseData(JSONArray array){
        for(int i  0; i<array.length(); i++) {
            SuperHeroes superHero  new SuperHeroes();
            CardAdapter car  new CardAdapter();
            JSONObject json  null;
            try {
                json  array.getJSONObject(i);
                superHero.setImageUrl(json.getString(Config.TAG_IMAGE_URL));
                Img json.getString(Config.TAG_IMAGE_URL);
                superHero.setName(json.getString(Config.TAG_NAME));
                superHero.setRank(json.getInt(Config.TAG_RANK));
                // superHero.setRealName(json.getString(Config.TAG_REAL_NAME));
                //superHero.setCreatedBy(json.getString(Config.TAG_CREATED_BY));
                //superHero.setFirstAppearance(json.getString(Config.TAG_FIRST_APPEARANCE));
                int rank  json.getInt("pid");

                // updating offset value to highest value
                if (rank > offSet)
                    offSet  rank;

                //  ArrayList<String> powers  new ArrayList<String>();

                //JSONArray jsonArray  json.getJSONArray(Config.TAG_POWERS);

               /* for(int j  0; j<jsonArray.length(); j++){
                    powers.add(((String) jsonArray.get(j))+"\n");
                }*/
                //superHero.setPowers(powers);
                Log.d("test",Img);
                car.setImageUrl(Img);


            } catch (JSONException e) {
                e.printStackTrace();
            }
            listSuperHeroes.add(superHero);

        }

        //Finally initializing our adapter
        adapter  new CardAdapter(listSuperHeroes, this);

        //Adding adapter to recyclerview
        recyclerView.setAdapter(adapter);

    }


    @Override
    public void onRefresh() {
        listSuperHeroes.clear();

       refreshItems();
    }
    void refreshItems() {
        // Load items
        getData();

        // Load complete
        onItemsLoadComplete();
    }
    void onItemsLoadComplete() {
        // Update the adapter and notify data set changed
        adapter.notifyDataSetChanged();
        //Finally initializing our adapter
        adapter  new CardAdapter(listSuperHeroes, this);

        //Adding adapter to recyclerview
        recyclerView.setAdapter(adapter);

        // Stop refresh animation

    }
} 

EndlessRecyclerOnScrollListener class code:

 package com.example.tatson.bila;

/**
 * Created by Tatson on 23-11-2015.
 */
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;

public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener {
    public static String TAG  EndlessRecyclerOnScrollListener.class.getSimpleName();

    private int previousTotal  0; // The total number of items in the dataset after the last load
    private boolean loading  true; // True if we are still waiting for the last set of data to load.
    private int visibleThreshold  5; // The minimum amount of items to have below your current scroll position before loading more.
    int firstVisibleItem, visibleItemCount, totalItemCount;

    private int current_page  1;

    private LinearLayoutManager mLinearLayoutManager;

    public EndlessRecyclerOnScrollListener(LinearLayoutManager linearLayoutManager) {
        this.mLinearLayoutManager  linearLayoutManager;
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        visibleItemCount  recyclerView.getChildCount();
        totalItemCount  mLinearLayoutManager.getItemCount();
        firstVisibleItem  mLinearLayoutManager.findFirstVisibleItemPosition();

        if (loading) {
            if (totalItemCount > previousTotal) {
                loading  false;
                previousTotal  totalItemCount;
            }
        }
        if (!loading ) {
            // End has been reached

            // Do something
            current_page++;
            Log.d("End", "Sucess");

            onLoadMore(current_page);

            loading  true;
        }
    }

    public abstract void onLoadMore(int current_page);
}

Thank you.

Solution

I found an answer here that, I believe, is much better than most I’ve seen on SO and elsewhere.

The idea is simple: in onScrolled in your RecyclerView’s ScrollListener, check if the last completely visible item is the last item in your data set.

        if(llm.findLastCompletelyVisibleItemPosition()  data.length() -1){
            //bottom of list!
            loadMoreData();
        }

This happens with a method in the LinearLayoutManager. Calling LinearLayoutManager#findLastCompletelyVisibleItemPosition() can comparing it to the position of the last item in your dataset let’s you know when you can load more.

I haven’t tried this for the GridLayoutManager.

UPDATE

LinearLayoutManager#findLastVisibleItemPosition() is a better alternative to LinearLayoutManager#findLastCompletelyVisibleItemPosition(), especially when your items are longer than the window height.

Answered By – wsgeorge

Leave a Comment