I want to implement endless scrolling in recyclerview
by calling new JSON request with increment of page number and adding those result with the previous results. first request shows 20 results but there are 200+ results left to show.How can i have endless scroll with onLoadMore()
function in 'TopratedFragment.java'.Please help with the codes
TopratedFragment.java
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
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.ImageLoader;
import com.android.volley.toolbox.JsonObjectRequest;
import com.example.mitab.mentor.Movies.Pages.L;
import com.example.mitab.mentor.Movies.Pages.MyApplication;
import com.example.mitab.mentor.Movies.Pages.VolleySingleton;
import com.example.mitab.mentor.Movies.Pages.movie;
import com.example.mitab.mentor.R;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import android.os.Handler;
import static com.example.mitab.mentor.Movies.Pages.Keys.EndpointToprated.*;
/**
* A simple {@link Fragment} subclass.
* Use the {@link TopratedFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class TopratedFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
public static final String Top_rated="http://api.themoviedb.org/3/movie/top_rated";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
protected Handler handler;
private VolleySingleton volleySingleton;
private ImageLoader imageLoader;
int page=1;
private RequestQueue requestQueue;
private ArrayList<movie> listMovies=new ArrayList<>();
private ArrayList<movie> newlistMovies=new ArrayList<>();
private SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
private RecyclerView listMovieHits;
private AdapterToprated adapterToprated;
boolean loadingMore = false;
private int lastVisibleItemId=0;
public TopratedFragment() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static TopratedFragment newInstance(String param1, String param2) {
TopratedFragment fragment = new TopratedFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
volleySingleton= VolleySingleton.getsInstance();
requestQueue=volleySingleton.getRequestQueue();
sendJsonRequest();
}
private void sendJsonRequest(){
JsonObjectRequest request=new JsonObjectRequest(Request.Method.GET, getRequestUrl(page), (String)null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
listMovies=parseJSONResponse(response);
adapterToprated.setMovieList(listMovies);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(request);
}
private ArrayList<movie> parseJSONResponse(JSONObject response){
ArrayList<movie> listMovies=new ArrayList<>();
if (response==null || response.length()>0){
try {
JSONArray arrayMovies=response.getJSONArray(KEY_MOVIES);
for (int i=0;i<arrayMovies.length();i++){
long id=-1;
String title="NA";
String poster="NA";
String release="NA";
String overview="NA";
String vote="NA";
String votecount="NA";
JSONObject currentMovie=arrayMovies.getJSONObject(i);
//get the id of current movie
if (currentMovie.has(KEY_ID)&& !currentMovie.isNull(KEY_ID)){
id=currentMovie.getLong(KEY_ID);
}
if (currentMovie.has(KEY_TITLE)&& !currentMovie.isNull(KEY_TITLE)){
title=currentMovie.getString(KEY_TITLE);
}
if (currentMovie.has(KEY_POSTER_PATH)&& !currentMovie.isNull(KEY_POSTER_PATH)){
poster=currentMovie.getString(KEY_POSTER_PATH);
}
if (currentMovie.has(KEY_RELEASE_DATE)&& !currentMovie.isNull(KEY_RELEASE_DATE)){
release=currentMovie.getString(KEY_RELEASE_DATE);
}
if (currentMovie.has(KEY_OVERVIEW)&& !currentMovie.isNull(KEY_OVERVIEW)){
overview=currentMovie.getString(KEY_OVERVIEW);
}
if (currentMovie.has(KEY_AVERAGE_VOTE)&& !currentMovie.isNull(KEY_AVERAGE_VOTE)){
vote=currentMovie.getString(KEY_AVERAGE_VOTE);
}
if (currentMovie.has(KEY_VOTE_COUNT)&& !currentMovie.isNull(KEY_VOTE_COUNT)){
votecount=currentMovie.getString(KEY_VOTE_COUNT);
}
JSONArray genre=currentMovie.getJSONArray(KEY_GENRE_IDS);
if (currentMovie.has(KEY_GENRE_IDS)&& !currentMovie.isNull(KEY_GENRE_IDS)){
for (int j=0;j<genre.length();j++){
try {
String itemInArray=genre.getString(j);
}
catch (JSONException e){
}
}
}
movie movie=new movie();
movie.setId(id);
movie.setTitle(title);
movie.setOverview(overview);
movie.setAveragevote(vote);
Date date=null;
try {
date=dateFormat.parse(release);
}
catch (ParseException e){
}
movie.setReleasedate(date);
movie.setImage(poster);
movie.setVotecount(votecount);
if (id!=-1 && !title.equals("NA"))
{
listMovies.add(movie);
}
}
}
catch (JSONException e){
}
}
return listMovies;
}
public static String getRequestUrl(int page){
return Top_rated +"?api_key="+ MyApplication.API_KEY + "&page="+page;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_toprated, container, false);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
handler=new Handler();
listMovieHits=(RecyclerView) view.findViewById(R.id.listMovieHits);
listMovieHits.setLayoutManager(linearLayoutManager);
adapterToprated=new AdapterToprated(getActivity());
listMovieHits.setAdapter(adapterToprated);
//sendJsonRequest();
// Add the scroll listener
listMovieHits.addOnScrollListener(new EndlessRecyclerViewScrollListener(linearLayoutManager) {
@Override
public void onLoadMore(int page, int totalItemsCount) {
loadingMore=true;
sendJsonRequest();
int curlsize=adapterToprated.getItemCount();
listMovies.addAll(newlistMovies);
adapterToprated.notifyItemRangeChanged(curlsize,listMovies.size()-2);
}
});
// Inflate the layout for this fragment
return view;
}
}
AdapterToprated.java
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.example.mitab.mentor.MainActivity;
import com.example.mitab.mentor.Movies.Pages.L;
import com.example.mitab.mentor.Movies.Pages.VolleySingleton;
import com.example.mitab.mentor.Movies.Pages.movie;
import com.example.mitab.mentor.R;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
public class AdapterToprated extends RecyclerView.Adapter<AdapterToprated.ViewHolderToprated> {
private LayoutInflater layoutInflater;
private VolleySingleton volleySingleton;
private ImageLoader imageLoader;
private ArrayList<movie> listMovies=new ArrayList<movie>();
private SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
private RecyclerView.OnItemTouchListener onItemTouchListener;
Context context;
public AdapterToprated(Context context){
layoutInflater=LayoutInflater.from(context);
volleySingleton=VolleySingleton.getsInstance();
imageLoader=volleySingleton.getImageLoader();
this.context = context;
}
public void setMovieList(ArrayList<movie> listMovies){
this.listMovies=listMovies;
notifyItemRangeChanged(0, listMovies.size());
}
@Override
public ViewHolderToprated onCreateViewHolder(ViewGroup parent, int viewType) {
View view=layoutInflater.inflate(R.layout.individual_toprated, parent, false);
ViewHolderToprated viewHolderToprated=new ViewHolderToprated(view);
return viewHolderToprated;
}
@Override
public void onBindViewHolder(final ViewHolderToprated holder, int position) {
final movie currentMovie=listMovies.get(position);
holder.movieTitle.setText(currentMovie.getTitle());
Date movieReleaseDate=currentMovie.getReleasedate();
if (movieReleaseDate!=null){
String formattedDate=dateFormat.format(movieReleaseDate);
holder.movieReleaseDate.setText(formattedDate);
}else{
holder.movieReleaseDate.setText("NA");
}
holder.movieRating.setText(currentMovie.getAveragevote());
String urlThumnail=currentMovie.getImage();
if (!urlThumnail.equals("NA")){
imageLoader.get(urlThumnail, new ImageLoader.ImageListener() {
@Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
holder.movieThumbnail.setImageBitmap(response.getBitmap());
}
@Override
public void onErrorResponse(VolleyError error) {
}
});
}
holder.lnrLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(context,Intentpass.class);
Bundle extras=new Bundle();
extras.putString("Title","currentMovie.getTitle()");
extras.putString("Date","formattedDate");
extras.putString("Rating","currentMovie.getAveragevote()");
intent.putExtras(extras);
context.startActivity(intent);
//intent.putExtra("details",currentMovie.getTitle());
//context.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return listMovies.size();
}
static class ViewHolderToprated extends RecyclerView.ViewHolder{
private ImageView movieThumbnail;
private TextView movieTitle;
private TextView movieReleaseDate;
private TextView movieRating;
private RelativeLayout lnrLayout;
public ViewHolderToprated(View itemView) {
super(itemView);
movieThumbnail=(ImageView) itemView.findViewById(R.id.movieThumbnail);
movieTitle=(TextView) itemView.findViewById(R.id.movieTitle);
movieReleaseDate=(TextView) itemView.findViewById(R.id.movieReleaseDate);
movieRating=(TextView) itemView.findViewById(R.id.movieRating);
lnrLayout=(RelativeLayout)itemView.findViewById(R.id.lnLayout);
}
}
}
EndlessRecyclerViewScrollListener.java
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
public abstract class EndlessRecyclerViewScrollListener extends RecyclerView.OnScrollListener {
// The minimum amount of items to have below your current scroll position
// before loading more.
private int visibleThreshold = 5;
// The current offset index of data you have loaded
private int currentPage = 0;
// The total number of items in the dataset after the last load
private int previousTotalItemCount = 0;
// True if we are still waiting for the last set of data to load.
private boolean loading = true;
// Sets the starting page index
private int startingPageIndex = 0;
RecyclerView.LayoutManager mLayoutManager;
public EndlessRecyclerViewScrollListener(LinearLayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
}
public EndlessRecyclerViewScrollListener(GridLayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
visibleThreshold = visibleThreshold * layoutManager.getSpanCount();
}
public EndlessRecyclerViewScrollListener(StaggeredGridLayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
visibleThreshold = visibleThreshold * layoutManager.getSpanCount();
}
public int getLastVisibleItem(int[] lastVisibleItemPositions) {
int maxSize = 0;
for (int i = 0; i < lastVisibleItemPositions.length; i++) {
if (i == 0) {
maxSize = lastVisibleItemPositions[i];
}
else if (lastVisibleItemPositions[i] > maxSize) {
maxSize = lastVisibleItemPositions[i];
}
}
return maxSize;
}
// This happens many times a second during a scroll, so be wary of the code you place here.
// We are given a few useful parameters to help us work out if we need to load some more data,
// but first we check if we are waiting for the previous load to finish.
@Override
public void onScrolled(RecyclerView view, int dx, int dy) {
int lastVisibleItemPosition = 0;
int totalItemCount = mLayoutManager.getItemCount();
if (mLayoutManager instanceof StaggeredGridLayoutManager) {
int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(null);
// get maximum element within the list
lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions);
} else if (mLayoutManager instanceof LinearLayoutManager) {
lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition();
} else if (mLayoutManager instanceof GridLayoutManager) {
lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition();
}
// If the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
if (totalItemCount < previousTotalItemCount) {
this.currentPage = this.startingPageIndex;
this.previousTotalItemCount = totalItemCount;
if (totalItemCount == 0) {
this.loading = true;
}
}
// If it’s still loading, we check to see if the dataset count has
// changed, if so we conclude it has finished loading and update the current page
// number and total item count.
if (loading && (totalItemCount > previousTotalItemCount)) {
loading = false;
previousTotalItemCount = totalItemCount;
}
// If it isn’t currently loading, we check to see if we have breached
// the visibleThreshold and need to reload more data.
// If we do need to reload some more data, we execute onLoadMore to fetch the data.
// threshold should reflect how many total columns there are too
if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) {
currentPage++;
onLoadMore(currentPage, totalItemCount);
loading = true;
}
}
// Defines the process for actually loading more data based on page
public abstract void onLoadMore(int page, int totalItemsCount);
}