Android RecyclerView Load More on Scroll with Example - GeeksforGeeks

30 Apr, 2021
Many apps display so many amounts of data in the form of a list. This data is so much so that it cannot be loaded at a time. If we load this data at a time then it may take so much loading time and degrades the performance of our RecyclerView. So to solve this we generally load the data in chunks and display it at a time. In this article, we will take a look at loading this data by showing a ProgressBar and load data in the infinite list. 
We will be building a simple application in which we will be displaying the infinite list and we will load the data with the help of the ProgressBar below. We will be calling the same method to add data to our ArrayList. A sample GIF is given below to get an idea about what we are going to do in this article. Note that we are going to implement this project using the Java language. 
Step 1: Create a New Project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Java as the programming language.
Step 2: Add the below dependency in your build.gradle file and allow internet permission in the manifests file
Below is the dependency for Volley which we will be using to get the data from API. For adding this dependency navigate to the app > Gradle Scripts > build.gradle(app) and add the below dependency in the dependencies section. We have used the Picasso dependency for image loading from the URL.  
// below line is used for volley library
implementation ‘com.android.volley:volley:1.1.1’

// below line is used for image loading library
implementation ‘com.squareup.picasso:picasso:2.71828’
Add internet permission in the manifests file.
<uses-permission android:name="android.permission.INTERNET"/>
Step 3: Working with the activity_main.xml file
Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for the activity_main.xml file. 
XML
<?xml version="1.0" encoding="utf-8"?><androidx.core.widget.NestedScrollView    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/idNestedSV"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity">      <!--linear layout for displaying        our recycler view-->    <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:orientation="vertical">          <!--recycler view for displaying our list of data            and we are making nested scroll for our            recycler view as false-->        <androidx.recyclerview.widget.RecyclerView            android:id="@+id/idRVCourses"            android:layout_width="match_parent"            android:layout_height="0dp"            android:layout_weight="1"            android:nestedScrollingEnabled="false" />          <!--we are adding progress bar            for the purpose of loading-->        <ProgressBar            android:id="@+id/idPBLoading"            android:layout_width="match_parent"            android:layout_height="wrap_content" />    </LinearLayout>  </androidx.core.widget.NestedScrollView>
Step 4: Working with Modal Class 
Navigate to the app > java > your app’s package name > Right-click on it > New > Java class and name it as CourseModal and add the below code to it. 
Java
public class CourseModal {      // variables for our course name,    // description and duration.    private String courseName;    private String courseModes;    private String courseTracks;    private String courseImg;      // constructor class.    public CourseModal(String courseName, String courseModes, String courseTracks, String courseImg) {        this.courseName = courseName;        this.courseModes = courseModes;        this.courseTracks = courseTracks;        this.courseImg = courseImg;    }      // getter and setter methods.    public String getCourseImg() {        return courseImg;    }      public void setCourseImg(String courseImg) {        this.courseImg = courseImg;    }      public String getCourseName() {        return courseName;    }      public void setCourseName(String courseName) {        this.courseName = courseName;    }      public String getcourseModes() {        return courseModes;    }      public void setcourseModes(String courseModes) {        this.courseModes = courseModes;    }      public String getcourseTracks() {        return courseTracks;    }      public void setcourseTracks(String courseTracks) {        this.courseTracks = courseTracks;    }}
Step 5: Creating a layout file for our item of RecyclerView
Navigate to the app > res > layout > Right-click on it > New > Layout Resource File and name it as course_rv_item and add the below code to it. 
XML
<?xml version="1.0" encoding="utf-8"?><androidx.cardview.widget.CardView     xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:id="@+id/idCVCOurseItem"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_margin="5dp"    app:cardCornerRadius="6dp"    app:cardElevation="4dp">      <RelativeLayout        android:layout_width="match_parent"        android:layout_height="wrap_content">          <!--image view for displaying course image-->        <ImageView            android:id="@+id/idIVCourse"            android:layout_width="100dp"            android:layout_height="100dp"            android:layout_margin="10dp" />                  <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginStart="2dp"            android:layout_marginTop="10dp"            android:layout_marginEnd="2dp"            android:layout_toEndOf="@id/idIVCourse"            android:gravity="center"            android:orientation="vertical"            android:padding="4dp">              <!--Textview for displaying our Course Name-->            <TextView                android:id="@+id/idTVCourseName"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:padding="2dp"                android:text="CourseName"                android:textColor="@color/purple_500"                android:textSize="18sp"                android:textStyle="bold" />                          <!--Textview for displaying our Course Duration-->            <TextView                android:id="@+id/idTVCourseDuration"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:padding="2dp"                android:text="Duration"                android:textColor="@color/black" />                          <!--Textview for displaying our Course Description-->            <TextView                android:id="@+id/idTVCourseDescription"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:padding="2dp"                android:text="Description"                android:textColor="@color/black" />        </LinearLayout>      </RelativeLayout>      </androidx.cardview.widget.CardView>
Step 6: Creating an adapter class for setting our data 
Similarly, create another Java class and name it as CourseRVAdapter and add the below code to it. Comments are added in the code to get to know in more detail. 
Java
import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;  import androidx.annotation.NonNull;import androidx.recyclerview.widget.RecyclerView;  import com.squareup.picasso.Picasso;  import java.util.ArrayList;  public class CourseRVAdapter extends RecyclerView.Adapter<CourseRVAdapter.ViewHolder> {          private Context context;    private ArrayList<CourseModal> courseModalArrayList;      // creating a constructor class.    public CourseRVAdapter(Context context, ArrayList<CourseModal> courseModalArrayList) {        this.context = context;        this.courseModalArrayList = courseModalArrayList;    }      @NonNull    @Override    public CourseRVAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {        // passing our layout file for displaying our card item        return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.course_rv_item, parent, false));      }      @Override    public void onBindViewHolder(@NonNull CourseRVAdapter.ViewHolder holder, int position) {        // setting data to our text views from our modal class.        CourseModal courses = courseModalArrayList.get(position);        holder.courseNameTV.setText(courses.getCourseName());        holder.courseTracksTV.setText(courses.getcourseTracks());        holder.courseModesTV.setText(courses.getcourseModes());        Picasso.get().load(courses.getCourseImg()).into(holder.courseIV);    }      @Override    public int getItemCount() {        return courseModalArrayList.size();    }      public class ViewHolder extends RecyclerView.ViewHolder {        // creating variables for our text views.        private final TextView courseNameTV;        private final TextView courseTracksTV;        private final TextView courseModesTV;        private final ImageView courseIV;          public ViewHolder(@NonNull View itemView) {            super(itemView);            // initializing our text views.            courseIV = itemView.findViewById(R.id.idIVCourse);            courseNameTV = itemView.findViewById(R.id.idTVCourseName);            courseTracksTV = itemView.findViewById(R.id.idTVCourseDuration);            courseModesTV = itemView.findViewById(R.id.idTVCourseDescription);        }    }}
Step 7: Working with the MainActivity.java file
Go to the MainActivity.java file and refer to the following code. Below is the code for the MainActivity.java file. Comments are added inside the code to understand the code in more detail.
Java
import android.os.Bundle;import android.view.View;import android.widget.ProgressBar;import android.widget.Toast;  import androidx.appcompat.app.AppCompatActivity;import androidx.core.widget.NestedScrollView;import androidx.recyclerview.widget.LinearLayoutManager;import androidx.recyclerview.widget.RecyclerView;  import com.android.volley.Request;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 org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;  import java.util.ArrayList;  public class MainActivity extends AppCompatActivity {          // creating variables for our UI components.    int count = 0;    String url = "https://jsonkeeper.com/b/WO6S";    private ArrayList<CourseModal> courseArrayList;    private RecyclerView courseRV;    private CourseRVAdapter courseRVAdapter;    private ProgressBar loadingPB;    private NestedScrollView nestedSV;      @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                  // initializing our variables.        courseRV = findViewById(R.id.idRVCourses);        loadingPB = findViewById(R.id.idPBLoading);        nestedSV = findViewById(R.id.idNestedSV);                  // initializing our array list.        courseArrayList = new ArrayList<>();                  // calling a method to add data to our array list.        getData();                  // on below line we are setting layout manger to our recycler view.        LinearLayoutManager manager = new LinearLayoutManager(this);        courseRV.setLayoutManager(manager);        // adding on scroll change listener method for our nested scroll view.        nestedSV.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {            @Override            public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {                // on scroll change we are checking when users scroll as bottom.                if (scrollY == v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight()) {                    // in this method we are incrementing page number,                    // making progress bar visible and calling get data method.                    count++;                    // on below line we are making our progress bar visible.                    loadingPB.setVisibility(View.VISIBLE);                    if (count < 20) {                        // on below line we are again calling                        // a method to load data in our array list.                        getData();                    }                }            }        });    }      private void getData() {        // creating a new variable for our request queue        RequestQueue queue = Volley.newRequestQueue(MainActivity.this);        // in this case the data we are getting is in the form        // of array so we are making a json array request.        // below is the line where we are making an json array        // request and then extracting data from each json object.        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {            @Override            public void onResponse(JSONArray response) {                  courseRV.setVisibility(View.VISIBLE);                for (int i = 0; i < response.length(); i++) {                    // creating a new json object and                    // getting each object from our json array.                    try {                        // we are getting each json object.                        JSONObject responseObj = response.getJSONObject(i);                          // now we get our response from API in json object format.                        // in below line we are extracting a string with                        // its key value from our json object.                        // similarly we are extracting all the strings from our json object.                        String courseName = responseObj.getString("courseName");                        String courseTracks = responseObj.getString("courseTracks");                        String courseMode = responseObj.getString("courseMode");                        String courseImageURL = responseObj.getString("courseimg");                        courseArrayList.add(new CourseModal(courseName, courseMode, courseTracks, courseImageURL));                                                  // on below line we are adding our array list to our adapter class.                        courseRVAdapter = new CourseRVAdapter(MainActivity.this, courseArrayList);                                                  // on below line we are setting                         // adapter to our recycler view.                        courseRV.setAdapter(courseRVAdapter);                    } catch (JSONException e) {                        e.printStackTrace();                    }                }            }        }, new Response.ErrorListener() {            @Override            public void onErrorResponse(VolleyError error) {                Toast.makeText(MainActivity.this, "Fail to get the data..", Toast.LENGTH_SHORT).show();            }        });        queue.add(jsonArrayRequest);    }}
Now run your app and see the output of the app. 
Output:
Picked
Android
Java
Java
Android
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Flutter - Custom Bottom Navigation Bar
How to Read Data from SQLite Database in Android?
How to Post Data to API using Retrofit in Android?
Retrofit with Kotlin Coroutine in Android
Android Listview in Java with Example
Arrays in Java
Split() String method in Java with examples
For-each loop in Java
Reverse a string in Java
Arrays.sort() in Java with examples