Skip to content

Instantly share code, notes, and snippets.

@martijn00
Last active March 18, 2024 22:13
Show Gist options
  • Select an option

  • Save martijn00/a45a238c5452a273e602 to your computer and use it in GitHub Desktop.

Select an option

Save martijn00/a45a238c5452a273e602 to your computer and use it in GitHub Desktop.
Load more / endless scroll for Xamarin RecyclerView
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = base.OnCreateView(inflater, container, savedInstanceState);
var recyclerView = view.FindViewById<RecyclerView>(Resource.Id.my_recycler_view);
if (recyclerView != null)
{
recyclerView.HasFixedSize = true;
var layoutManager = new LinearLayoutManager(Activity);
var onScrollListener = new XamarinRecyclerViewOnScrollListener (layoutManager);
onScrollListener.LoadMoreEvent += (object sender, EventArgs e) => {
//Load more stuff here
};
recyclerView.AddOnScrollListener (onScrollListener);
recyclerView.SetLayoutManager(layoutManager);
}
return view;
}
public class XamarinRecyclerViewOnScrollListener : RecyclerView.OnScrollListener
{
public delegate void LoadMoreEventHandler(object sender, EventArgs e);
public event LoadMoreEventHandler LoadMoreEvent;
private LinearLayoutManager LayoutManager;
public XamarinRecyclerViewOnScrollListener (LinearLayoutManager layoutManager)
{
LayoutManager = layoutManager;
}
public override void OnScrolled (RecyclerView recyclerView, int dx, int dy)
{
base.OnScrolled (recyclerView, dx, dy);
var visibleItemCount = recyclerView.ChildCount;
var totalItemCount = recyclerView.GetAdapter().ItemCount;
var pastVisiblesItems = LayoutManager.FindFirstVisibleItemPosition();
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
LoadMoreEvent (this, null);
}
}
}
@eoinahern

Copy link
Copy Markdown

cool. going to use this in my app. Thanks!

@reyou

reyou commented Sep 25, 2016

Copy link
Copy Markdown

this helped a lot. thanks!

@PradeepLoganathan

Copy link
Copy Markdown

This is good.. but shouldn't it use the Recyclerview.layoutmanager rather than the linearlayoutmanager since we are using a recycler view ?

@mohamedzardheye

Copy link
Copy Markdown

thanks it works you saved my life

@ipanga

ipanga commented Sep 16, 2017

Copy link
Copy Markdown

Thanks for your simple and efficient solution. Be blessed !

@saeed131

Copy link
Copy Markdown

Hello thanks for your solution.
But i have not OnCreateView Method.
I want implement in MainActivity.
how to do this?

@Ruud-cb

Ruud-cb commented Dec 30, 2018

Copy link
Copy Markdown

Works fine, but unfortunately it fires multiple times so you should adjust it so it only fires ones until the loading of data is done again.

@kasunn25

kasunn25 commented Mar 12, 2019

Copy link
Copy Markdown

this is more accurate,

public class EndlessRecyclerOnScrollListener : RecyclerView.OnScrollListener
    {
        public delegate void LoadMoreEventHandler(object sender, EventArgs e);
        public event LoadMoreEventHandler LoadMoreEvent;

        private LinearLayoutManager LayoutManager;

        private int previousTotal = 0; // The total number of items in the dataset after the last load
        private bool loading = true; // True if we are still waiting for the last set of data to load.
        private bool animiFlag = true;
        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;

        public EndlessRecyclerOnScrollListener(LinearLayoutManager layoutManager)
        {
            LayoutManager = layoutManager;
        }

        public override void OnScrolled(RecyclerView recyclerView, int dx, int dy)
        {
            base.OnScrolled(recyclerView, dx, dy);

            visibleItemCount = recyclerView.ChildCount;
            totalItemCount = recyclerView.GetAdapter().ItemCount;
            firstVisibleItem = LayoutManager.FindFirstVisibleItemPosition();

            if (loading)
            {
                if (totalItemCount > previousTotal)
                {
                    loading = false;
                    previousTotal = totalItemCount;
                }
            }

            if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold))
            {
                current_page++;

                LoadMoreEvent(this, null);

                loading = true;
            }

            /*if ((visibleItemCount + pastVisiblesItems) >= totalItemCount)
            {
                LoadMoreEvent(this, null);
            }*/
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment