RecyclerView with EndlessScroll With Android Data Binding

A common application feature is to load automatically more items as the user scrolls through the items (aka infinite scroll). This is done by triggering a request for more data once the user crosses a threshold of remaining items before they’ve hit the end.

Implementing endless pagination for RecyclerView requires the following steps:

  1. Copy over the EndlessRecyclerViewOnScrollListener.java into your application. This is an abstract class.
  2. Now call addOnScrollListener() on your RecyclerView to enable endless scrolling and pass EndlessRecyclerViewOnScollListener as parameter in addOnScrollListener() and implement onLoadMore() method which would be called when user scroll down bottom in the list.
  3. In onLoadMore() method load your data using an api or some source from where you are fetching data.

activity_mail.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.sample.android.MainActivity">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/item_progress_bar"
            android:layout_marginTop="8dp" />

        <ProgressBar
            android:id="@+id/item_progress_bar"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:elevation="@dimen/padding_5"
            android:padding="@dimen/padding_5"
            android:visibility="gone" />
    </RelativeLayout>
</layout>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private List<String> mStringList;
    private int mLoadedItems = 0;
    private SampleAdapter mSampleAdapter;
    private ActivityMainBinding mActivityMainBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(MainActivity.this);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mActivityMainBinding.recyclerView.setLayoutManager(linearLayoutManager);
        mActivityMainBinding.recyclerView.addItemDecoration(new DividerItemDecoration(MainActivity.this, DividerItemDecoration.VERTICAL));
        mStringList = new ArrayList<>();
        mSampleAdapter = new SampleAdapter(mStringList);
        mActivityMainBinding.recyclerView.setAdapter(mSampleAdapter);
        addDataToList();

        mActivityMainBinding.recyclerView.addOnScrollListener(new EndlessRecyclerViewOnScrollListener(linearLayoutManager) {
            @Override
            public void onLoadMore() {
                addDataToList();
            }
        });
    }

    private void addDataToList() {
        mActivityMainBinding.itemProgressBar.setVisibility(View.VISIBLE);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i <= 30; i++) {
                    mStringList.add("SampleText : " + mLoadedItems);
                    mLoadedItems++;
                }
                mSampleAdapter.notifyDataSetChanged();
                mActivityMainBinding.itemProgressBar.setVisibility(View.GONE);
            }
        }, 1500);

    }
}

SampleAdapter.java

public class SampleAdapter extends RecyclerView.Adapter<SampleAdapter.ViewHolder> {
    private List<String> myList;

    public SampleAdapter(List<String> myList) {
        this.myList = myList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_my_list, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.textView.setText(myList.get(position));
    }

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

    static class ViewHolder extends RecyclerView.ViewHolder {
        AppCompatTextView textView;

        ViewHolder(View itemView) {
            super(itemView);
            textView = (AppCompatTextView) itemView.findViewById(R.id.text1);
        }
    }
}

item_my_list.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.AppCompatTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="@dimen/padding_10"
    android:text="@string/app_name"
    android:textColor="@android:color/black">

</android.support.v7.widget.AppCompatTextView>

Find the sample code here

To reset the state when reload the data from initial

to reset the state of endless recyclerview listener you just need to set previousTotal variable to 0.

endlessRecyclerListener.mProviousTotal = 0;

I would love to hear your own recommendations and experiences in the comments below. Please share your Valuable feedback.

Leave a comment