Open In App

Android RecyclerView Load More on Scroll with Example

Last Updated : 30 Sep, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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. 

What we are going to build in this article?

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. 

Android RecyclerView Load More on Scroll with Example Sample GIF

Step by Step Implementation

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: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
    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);
           
          //CardView itemClick listener
          itemView.setOnClickListener(new View.OnClickListener() {
                @Override public void onClick(View v) {
                    // item clicked
 
                    int a=getAdapterPosition();
                    CourseModal superHero =  courseModalArrayList.get(a);
                    Toast.makeText(context, "#" +  superHero.getCourseName() , Toast.LENGTH_SHORT).show();
 
                    //   Toast.makeText(context, "#" +  superHero.getTitle() , Toast.LENGTH_SHORT).show();
 
                }
            });
        }
    }
}


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 manager 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:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads