VSG24 VSG24 - 1 month ago 34
Android Question

NotifyDataSetChanged not working with Xamarin

I'm using RecyclerView with Xamarin.Android. I'm filling the adapter with a

List<Article>
. For adding more items to list when user scrolls down I'm using
RecyclerView.OnScrollListener
. It triggers an even and inside the event handler I'm retrieving the data and adding it to the old list with and then call
adapter.NotifyDataSetChanged ();
. It retrieves the data and triggers the event but doesn't update the recyclerview on the device.

What am I doing wrong??

RecyclerView recyclerview;
NewsAdapter adapter;
private List<Article> listofarticles;

var onScrollListener = new XamarinRecyclerViewOnScrollListener (layoutmanager);
onScrollListener.LoadMoreEvent += async (object sender, EventArgs e) => {
//Load more stuff here
Console.WriteLine ("*** loading more stuff ***");
var newarticles = await GetData ("2");
listofarticles = listofarticles.Concat (newarticles).ToList ();
adapter.NotifyDataSetChanged ();
};


Here's my adapter: (The clickhandler and itemcount methods are omitted)

// Adapter
public class NewsAdapter : RecyclerView.Adapter
{
// Event handler for item clicks:
public event EventHandler<int> ItemClick;
private Context globalContext = null;

// Underlying data set:
public List<Article> _listofarticles;

// Load the adapter with the data set (articles) at construction time:
public NewsAdapter (List<Article> listofarticle, Context context)
{
this._listofarticles = listofarticle;
globalContext = context;
}

// Create a new article CardView (invoked by the layout manager):
public override RecyclerView.ViewHolder OnCreateViewHolder (ViewGroup parent, int viewType)
{
// Inflate the CardView for the photo:
View itemView = LayoutInflater.From (parent.Context).Inflate (Resource.Layout.latestnews_recycler_article, parent, false);

// Create a ViewHolder to find and hold these view references, and
// register OnClick with the view holder:
NewsViewHolder vh = new NewsViewHolder (itemView, OnClick);
return vh;
}

// Fill in the contents of the article card (invoked by the layout manager):
public override void OnBindViewHolder (RecyclerView.ViewHolder holder, int position)
{
NewsViewHolder vh = holder as NewsViewHolder;

// Set the ImageView and TextView in this ViewHolder's CardView
// from this position in the photo album:

//vh.Thumbnail.SetImageResource (_listofarticles[position].Thumbnail);

// We use Picasso to load images efficiently
Picasso.With (globalContext).Load (_listofarticles[position].Thumbnail)
//.Placeholder(R.drawable.ic_placeholder) // optional
//.Error(R.drawable.ic_error_fallback) // optional
//.Resize(250, 200) // optional
//.Rotate(90) // optional
.Into (vh.Thumbnail);
vh.Title.Text = _listofarticles[position].Title;
}
}

Answer

I needed to add new items to the list inside adapter (not the one for the activity class) that is _listofarticles and then call NotifyDataSetChanged inside the adapter class like this.NotifyDataSetChanged ();. So to achieve that I added a method called AddToList to the adapter:

        public void AddToList(List<Article> newitemslist)
        {
            _listofarticles = _listofarticles.Concat (newitemslist).ToList ();
            this.NotifyDataSetChanged ();
        }

and I call it inside the event handler for scrolling like:

            var newarticles = await GetData ("2");
            adapter.AddToList (newarticles);

This properly updates the adapter and adds items to the end of recyclerview.

Comments