---
title: "Endless Recycler view with loader"  
description: "EndlessRecylcer view in android Endless scrolling in android works similar to paging in web apps. Here it works just by scrolling upward. This class E"  
author: "Prateek sharma"  
published: 2018-04-07  
updated: 2018-04-07  
canonical: https://www.mindstick.com/blog/11731/endless-recycler-view-with-loader  
category: "android apps"  
tags: ["android"]  
reading_time: 9 minutes  

---

# Endless Recycler view with loader

**EndlessRecylcer view in [android](https://www.mindstick.com/articles/13046/10-reasons-why-i-prefer-android-vs-iphone-ios)**

Endless scrolling in android works similar to paging in [web apps](https://www.mindstick.com/forum/159941/what-are-the-best-practices-for-handling-user-sessions-and-cookies-in-web-apps). Here it works just by scrolling upward. This class EndlessRecyclerViewScrollListener can be called from any class where you have implemented your recycler view.The below code will automatically [increment](https://www.mindstick.com/forum/173/auto-increment-id) the page and makes the request to the server with a new page number.

```
scrollListener = new EndlessRecyclerViewScrollListener(layoutManager) {                @Override                public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {                    page = totalItemsCount / 10;                    page = page + 1;                    loadMoreData(page);                }            };
```

\
EndlessRecyclerViewScrollListener is the main class which performs the scrolling [behavior](https://www.mindstick.com/forum/159354/runtimeexception-and-exception-behavior) of the application.

```
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 GridLayoutManager) {            lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition();        } else if (mLayoutManager instanceof LinearLayoutManager) {            lastVisibleItemPosition = ((LinearLayoutManager) 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, view);            loading = true;        }    }    // Call this method whenever performing new searches    public void resetState() {        this.currentPage = this.startingPageIndex;        this.previousTotalItemCount = 0;        this.loading = true;    }    // Defines the process for actually loading more data based on page    public abstract void onLoadMore(int page, int totalItemsCount, RecyclerView view);}
```

When you will receive a [response](https://www.mindstick.com/forum/12719/how-to-make-response-write-display-special-character-like-lt-gt) with a new list you need to append the new list with the [previous](https://yourviews.mindstick.com/view/81421/unlock-2-0-is-just-like-previous-corona-lockdowns) list.So for that purpose, you can use the following code. First, it checks if the previous list is empty or not, if not it appends the new list with the previous list and if the original list is empty it passes it as a new list.After the list is passed to the adapter you need to [register](https://www.mindstick.com/blog/220/registering-client-script-in-asp-dot-net) the recycler view with the scroll listener.\

```
Type collectionType = new TypeToken<Collection<TagMaster>>() {}.getType();                if(questionSortModelList.size()<=0) {
    questionSortModelList = gson.fromJson(modelList, collectionType);    mAdapter = new TagFragmentAdapter(getContext(), questionSortModelList);    mAdapter.setLoaded(true);    mRecyclerView.setAdapter(mAdapter);    progressBar.setVisibility(View.GONE);    }            else {    List<TagMaster> questionData= gson.fromJson(modelList, collectionType);    questionSortModelList.addAll(questionData);    int size = mAdapter.getItemCount();    mAdapter.notifyItemRangeInserted(size, questionSortModelList.size() - 1);    mAdapter.setLoaded(true);    // mAdapter = new RecentActivityAdapter(getContext(), questionSortModelList);    }    mRecyclerView.addOnScrollListener(scrollListener);
```

\

To the same recycler view, you can add a loader at the bottom of the page by adding the following line of code.

You just need to [update your](https://answers.mindstick.com/qa/32325/how-often-should-you-update-your-cover-photo-for-your-company-page) adapter for a loader to appear. First, you need to create a layout file for a loader.

```
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:gravity="center_horizontal">
    <ProgressBar        android:id="@+id/endless_progress"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:progress="25" />
</RelativeLayout>
```

\

Update the adapter. For this purpose, you just need to add a view holder for the [progress bar](https://www.mindstick.com/articles/12747/android-progress-bar) layout in your adapter and update the onCreateViewHolder and onBindViewHolder of the adapter.

```
public class TagFragmentAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<TagMaster> tagMasterList;    Context mContext;    protected boolean showLoader = false;    private static final int VIEWTYPE_ITEM = 0;    private static final int VIEWTYPE_LOADER = 1;    long loggedUserId = 0;

    public TagFragmentAdapter(Context context, List<TagMaster> tagMasters){        mContext = context;        tagMasterList = tagMasters;    }
    @Override    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerView.ViewHolder viewHolder = null;        LayoutInflater inflater = LayoutInflater.from(parent.getContext());        switch (viewType){            case VIEWTYPE_ITEM:                viewHolder = getViewHolder(parent, inflater);                break;            case VIEWTYPE_LOADER:                View view = inflater.inflate(R.layout.progress_bar_layout, parent, false);                viewHolder = new LoaderViewHolder(view);                break;        }        return viewHolder;    }
    @NonNull    private RecyclerView.ViewHolder getViewHolder(ViewGroup parent, LayoutInflater inflater) {        RecyclerView.ViewHolder viewHolder;        View v1 = inflater.inflate(R.layout.tag_fragment_view, parent, false);        viewHolder = new TagViewHolder(v1);        return viewHolder;    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)    @Override    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {        switch (getItemViewType(position)) {            case VIEWTYPE_ITEM:                final TagViewHolder holder = (TagViewHolder) viewHolder;                final TagMaster tagMaster = tagMasterList.get(position);                loggedUserId = Long.valueOf(SaveSharedPreference.getPrefUserId(mContext));                holder.tagName.setText(tagMaster.getName());                 break;            case VIEWTYPE_LOADER:                LoaderViewHolder holder1 = (LoaderViewHolder) viewHolder;                if (showLoader && tagMasterList.size() != 0){                   holder1.mProgressBar.setVisibility(View.VISIBLE);                }else {                    holder1.mProgressBar.setVisibility(View.GONE);                }                break;        }    }
   public void setLoaded(Boolean loader) {        showLoader = loader;    }
    @Override    public int getItemViewType(int position) {        return (position == tagMasterList.size() - 1 && showLoader) ? VIEWTYPE_LOADER : VIEWTYPE_ITEM;    }

    @Override    public int getItemCount() {        return tagMasterList.size();    }

    public class TagViewHolder extends RecyclerView.ViewHolder{
        //public TextView catergory;        private TextView tagName, quesTags;        private View mView;        private ImageButton favButton;
        public TagViewHolder(View view){            super(view);            tagName = (TextView) view.findViewById(R.id.tag_view);            quesTags = (TextView) view.findViewById(R.id.que_tags);            favButton = (ImageButton) view.findViewById(R.id.fav_tags);            mView = view;        }    }
    public class LoaderViewHolder extends RecyclerView.ViewHolder {        ProgressBar mProgressBar;        public LoaderViewHolder(View itemView) {            super(itemView);            mProgressBar = (ProgressBar) itemView.findViewById(R.id.endless_progress);        }    }}
```

---

Original Source: https://www.mindstick.com/blog/11731/endless-recycler-view-with-loader

Copyright © MindStick Software Pvt. Ltd. This Markdown version is provided for developers, AI systems, and offline reading.
