Last updated on January 5th, 2020 at 09:17 pm
In this post I am going to explain to you how we can implement load more on scroll load in recycler view Android application. Load more work like this “((visibleItemCount + pastVisibleItems) >= totaltemCount)” when we scroll our recycler view and we reach to end then we load more data. To learn this I can explain it in the simple step below.
Load more data on scroll RecyclerView
Step 1. Create a new Android project in Android studio.
Step 2. Once the project created add required library for this project, I am using Okhttp 3 and Glide library to load data from API and show an image using the Glide library.
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'com.android.support:recyclerview-v7:28.0.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' implementation("com.squareup.okhttp3:okhttp:4.2.1") implementation 'com.github.bumptech.glide:glide:4.8.0' }
Step 3. Now once library sync successfully we need to add Internet permission to load API from the server. Open AndroidManifest.xml and add internet permission in it.
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
Step 4. Now create a new layout file (user_list.xml) which we use in the recycler view.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10dp"> <ImageView android:id="@+id/image" android:layout_width="44dp" android:layout_height="44dp" /> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:text="" /> </LinearLayout> </LinearLayout>
Step 5. After layout creates two package adapter and model. Adapter set data in view and Model hold data that we get from API.
UserListAdapter
package com.scrollmorerecyclerview.adapter; import android.app.Activity; 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.ImageView; import android.widget.TextView; import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.bumptech.glide.request.RequestOptions; import com.scrollmorerecyclerview.R; import com.scrollmorerecyclerview.model.UserModel; import java.util.ArrayList; import java.util.List; public class UserListAdapter extends RecyclerView.Adapter<UserListAdapter.CustomViewHolder> { private List<UserModel> imageModelsList; private Context mContext; private Activity act; public UserListAdapter(Context context, ArrayList<UserModel> imageList, Activity activity) { this.imageModelsList = imageList; this.mContext = context; this.act = activity; } @Override public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(this.mContext).inflate(R.layout.user_list, parent, false); CustomViewHolder viewHolder = new CustomViewHolder(view); return viewHolder; } @Override public void onBindViewHolder(CustomViewHolder holder, final int position) { final UserModel get = imageModelsList.get(position); holder.name.setText(get.getName()); final String image = get.getImage(); RequestOptions options = new RequestOptions(); Glide .with(this.mContext) .load(image) .apply(new RequestOptions().transforms(new CenterCrop(), new RoundedCorners(10))) .into(holder.image); holder.name.setText(get.getName()); } @Override public int getItemCount() { return (null != imageModelsList ? imageModelsList.size() : 0); } @Override public long getItemId(int position) { return position; } @Override public int getItemViewType(int position) { return position; } class CustomViewHolder extends RecyclerView.ViewHolder { ImageView image; TextView name; public CustomViewHolder(View itemView) { super(itemView); image = (ImageView) itemView.findViewById(R.id.image); name = (TextView) itemView.findViewById(R.id.name); } } }
UserModel
package com.scrollmorerecyclerview.model; public class UserModel { int id; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getImage() { return image; } public void setImage(String image) { this.image = image; } public String getName() { return name; } public void setName(String name) { this.name = name; } String image, name; }
Step 6. Now we open activity_main.xml file and add RecyclerView in it.
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout 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" tools:context=".MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="match_parent"></android.support.v7.widget.RecyclerView> </android.support.constraint.ConstraintLayout>
Step 7. Now open your MainActivity.java file and in this, we load data from API and set in RecyclerView. I create a simple function through which we call API. For this post, I am using reqres.in you can use there API it’s free and easy to use.
public void getUserList(){ Request request = new Request.Builder() .url("https://reqres.in/api/users?per_page=15&page=1") .header("Accept", "application/json") .header("Content-Type", "application/json") .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { String mMessage = e.getMessage().toString(); Log.w("failure Response", mMessage); call.cancel(); } @Override public void onResponse(Call call, Response response) throws IOException { final String mMessage = response.body().string(); MainActivity.this.runOnUiThread(new Runnable() { @Override public void run() { try { JSONObject response = new JSONObject(mMessage); JSONArray users = response.getJSONArray("data"); for (int i = 0; i < users.length(); i++){ JSONObject user = users.getJSONObject(i); UserModel userModel = new UserModel(); userModel.setName(user.getString("first_name")); userModel.setImage(user.getString("avatar")); userModelArrayList.add(userModel); } userListAdapter.notifyDataSetChanged(); loading = false; } catch (JSONException e) { e.printStackTrace(); } } }); } }); }
Now call this method inside onCreate. I already find RecyclerView and already initialize adapter, you will get complete code at the bottom.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); list = (RecyclerView)findViewById(R.id.list); linearLayoutManager = new LinearLayoutManager(getApplicationContext()); list.setLayoutManager(linearLayoutManager); userModelArrayList = new ArrayList<>(); userListAdapter = new UserListAdapter(this, userModelArrayList, this); list.setAdapter(userListAdapter); getUserList(); }
Now our code load data from API and display in View. Now if you want to add a load more in RecyclerView we need to add addOnScrollListener to load more data on a scroll as shown in below code
list.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { if (dy > 0) { visibleItemCount = linearLayoutManager.getChildCount(); totalItemCount = linearLayoutManager.getItemCount(); pastVisibleItems = linearLayoutManager.findFirstVisibleItemPosition(); if (!loading) { if ((visibleItemCount + pastVisibleItems) >= totalItemCount) { loading = true; //page = page+1; getUserList(); } } } } });
I am using the same function to load data again on scroll load you pass your parameter to load actual data. Here is complete code of MainActivity.java
package com.scrollmorerecyclerview; 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 com.scrollmorerecyclerview.adapter.UserListAdapter; import com.scrollmorerecyclerview.model.UserModel; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.util.ArrayList; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public class MainActivity extends AppCompatActivity { RecyclerView list; ArrayList<UserModel> userModelArrayList; UserListAdapter userListAdapter; LinearLayoutManager linearLayoutManager; int page = 1; OkHttpClient client = new OkHttpClient(); int pastVisibleItems, visibleItemCount, totalItemCount; Boolean loading = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); list = (RecyclerView)findViewById(R.id.list); linearLayoutManager = new LinearLayoutManager(getApplicationContext()); list.setLayoutManager(linearLayoutManager); userModelArrayList = new ArrayList<>(); userListAdapter = new UserListAdapter(this, userModelArrayList, this); list.setAdapter(userListAdapter); list.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { if (dy > 0) { visibleItemCount = linearLayoutManager.getChildCount(); totalItemCount = linearLayoutManager.getItemCount(); pastVisibleItems = linearLayoutManager.findFirstVisibleItemPosition(); if (!loading) { if ((visibleItemCount + pastVisibleItems) >= totalItemCount) { loading = true; //page = page+1; getUserList(); } } } } }); getUserList(); } public void getUserList(){ Request request = new Request.Builder() .url("https://reqres.in/api/users?per_page=15&page=1") .header("Accept", "application/json") .header("Content-Type", "application/json") .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { String mMessage = e.getMessage().toString(); Log.w("failure Response", mMessage); call.cancel(); } @Override public void onResponse(Call call, Response response) throws IOException { final String mMessage = response.body().string(); MainActivity.this.runOnUiThread(new Runnable() { @Override public void run() { try { JSONObject response = new JSONObject(mMessage); JSONArray users = response.getJSONArray("data"); for (int i = 0; i < users.length(); i++){ JSONObject user = users.getJSONObject(i); UserModel userModel = new UserModel(); userModel.setName(user.getString("first_name")); userModel.setImage(user.getString("avatar")); userModelArrayList.add(userModel); } userListAdapter.notifyDataSetChanged(); loading = false; } catch (JSONException e) { e.printStackTrace(); } } }); } }); } }
You can download the complete code from the below link.
https://github.com/anehkumar/scroll-load-more-data-on-recyclerview