NotifyDataSetChanged 不适用于 Xamarin

NotifyDataSetChanged not working with Xamarin

我在 Xamarin.Android 中使用 RecyclerView。我正在用 List<Article> 填充适配器。为了在用户向下滚动时向列表中添加更多项目,我使用 RecyclerView.OnScrollListener。它触发事件处理程序,我正在检索数据并将其添加到旧列表,然后调用 adapter.NotifyDataSetChanged ();。它检索数据并触发事件,但不更新设备上的回收视图。

我哪里做错了??

    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 ();
        };

这是我的适配器:(省略了 clickhandler 和 itemcount 方法)

// 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;
        }
    }

我需要将新项目添加到列表 内部适配器(不是 activity class 的那个),即 _listofarticles然后像 this.NotifyDataSetChanged (); 一样在适配器 class 中调用 NotifyDataSetChanged。因此,为了实现这一点,我向适配器添加了一个名为 AddToList 的方法:

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

我在事件处理程序中调用它进行滚动,例如:

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

这会正确更新适配器并将项目添加到 recyclerview 的末尾。

在 Xamarin 中,由于使用 ArrayAdapter 时的内存管理和垃圾收集,实现会在您创建后备列表时复制它。

为了能够使用 NotifyDataSetChanged,您需要使用 Android.Runtime.JavaList 而不是 .Net IList.

这是一个片段:

ArrayAdapter adapter;
Android.Runtime.JavaList<string> messages = new Android.Runtime.JavaList<string>();

然后在 OnCreateOnResume 中添加以下代码:

adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1, Android.Resource.Id.Text1, messages);
listView.Adapter = adapter;

您现在可以将项目添加到您的列表并调用 NotifyDataSetChanged,您应该能够获得更改。

就我而言,我在更新列表视图的按钮上有一个点击处理程序:

    void BtnSend_Click(object sender, System.EventArgs e)
    {
        var message = editText.Text;
        messages.Add(message);
        adapter.NotifyDataSetChanged();
    }