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.
We can use a RecyclerView inside another RecyclerView. We refer to this as nested RecyclerView. It is an instance where one RecyclerView widget is the parent to another RecyclerView widget. A good example where a nested RecyclerView widget is implemented includes the Google Play Store.
Adapter , much like the built-in Android ArrayAdapter , will populate the data into the RecyclerView . It also converts a Java object into an individual list item View to be inserted and displayed to the user.
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.
Check do you currently have items to scroll down -
if (! recyclerView.canScrollVertically(1))
If yes - load more items, for example, using HTTP client.
Full code:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (! recyclerView.canScrollVertically(1)){ //1 for down
loadMore();
}
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With