Calling NotifyAll to Update RecyclerView from External Method

Nathan Sokalski 4,116 Reputation points
2021-03-18T03:05:49.017+00:00

I have a RecyclerView (with an Adapter, ViewHolder, etc.), and I need to update the data (the IEnumerable passed to the Adapter). In order for this to be updated in the RecyclerView, I need to call NotifyAll(). However, this gives me the following message:

Java.Lang.IllegalMonitorStateException: 'object not locked by thread before notify()'

I have seen stuff about Java requiring synchronized locks & other stuff for this. I am not familiar with Java, and I am using C# for this Xamarin.Android app. This is my first Xamarin.Android app, so I am new to RecyclerView and Android. Can anybody help my figure out how to update my RecyclerView from an external method? Thanks.

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,291 questions
0 comments No comments
{count} votes

Accepted answer
  1. JessieZhang-MSFT 7,701 Reputation points Microsoft Vendor
    2021-03-18T06:38:39.323+00:00

    Hello,

    Welcome to our Microsoft Q&A platform!

    You can add a function in the Adapter of your RecyclerView(e.g. UpDateData) and call NotifyDataSetChanged in your Adapter .

    public void UpDateData(List<Photo> addedPhotos) {  
    
    mPhotoAlbum.AddRange(addedPhotos);  
    NotifyDataSetChanged();  
     }  
    

    You can refer to the full code of amy demo:
    1.my adapter PhotoAlbumAdapter:

    public class PhotoAlbumAdapter: RecyclerView.Adapter  
    {  
        public event EventHandler<int> ItemClick;  
        public static List<Photo> mPhotoAlbum = new List<Photo>();  
    
        public static RecyclerView.Adapter adapter;  
    
        public PhotoAlbumAdapter(List<Photo> branchesList)  
        {  
            adapter = this;  
            mPhotoAlbum = branchesList;  
        }  
      //  add function `UpDateData` here and call `NotifyDataSetChanged`  
        public void UpDateData(List<Photo> addedPhotos) {  
    
            mPhotoAlbum.AddRange(addedPhotos);  
            NotifyDataSetChanged();  
        }  
    
        public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)  
        {  
            View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.PhotoCardView, parent, false);  
    
            PhotoViewHolder vh = new PhotoViewHolder(itemView, OnClick);  
    
            return vh;  
        }  
    
        public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)  
        {  
            PhotoViewHolder vh = holder as PhotoViewHolder;  
            //***********************  
            Photo item=   mPhotoAlbum[position];  
    
            vh.Caption.Text = item.Caption;  
    
            vh.MyCheckBox.SetOnCheckedChangeListener(null);  
            vh.MyCheckBox.SetOnCheckedChangeListener(new MyListener(item));  
            vh.MyCheckBox.Checked = item.isChecked;  
    
            vh.DeleteButton.SetOnClickListener(new MyRemoveItem(item,position));  
    
        }  
    
    
        class MyRemoveItem : Java.Lang.Object, View.IOnClickListener  
        {  
            Photo photo;  
            int position;  
            public MyRemoveItem(Photo item,int position) {  
                this.photo = item;  
                this.position = position;  
            }  
    
            public void OnClick(View v)  
            {  
                mPhotoAlbum.Remove(photo);  
    
                adapter.NotifyDataSetChanged();  
            }  
        }  
    
    
    
        class MyListener : Java.Lang.Object, CompoundButton.IOnCheckedChangeListener  
        {  
            Photo photo;  
    
            public MyListener( Photo item)  
            {  
                this.photo = item;  
            }  
    
            public void OnCheckedChanged(CompoundButton buttonView, bool isChecked)  
            {  
                photo.isChecked = isChecked;  
            }  
        }  
    
        public override int ItemCount  
        {  
            get { return mPhotoAlbum.Count; }  
        }  
    
        // Raise an event when the item-click takes place:  
        void OnClick(int position)  
        {  
            if (ItemClick != null)  
                ItemClick(this, position);  
        }  
    }  
    

    2.when we click a button ,we can add some new data to the exsited list:

              refreshBtn = FindViewById<Button>(Resource.Id.refreshBtn);  
            refreshBtn.Click += delegate  
            {  
                List<Photo> photos = new List<Photo>();  
                photos.Add(new Photo{mPhotoID = Resource.Drawable.before_mobile_phones,mCaption = "Before mobile phones",isChecked=false });  
                photos.Add(new Photo {mPhotoID = Resource.Drawable.eurostar,mCaption = "Eurostar Train",isChecked=false });  
                mAdapter.UpDateData(photos);  
             };  
    

    Update:

    You can also try to put your code into the RunOnUiThread and change this.NotifyAll(); to NotifyDataSetChanged(); ,you can refer to the following code:

            refreshBtn.Click += delegate  
            {  
                Task.Run(() =>  
                {  
                    // Perform a task  
                    RunOnUiThread(() =>  
                    {  
                       // manipulate UI controls  
                       ((PhotoAlbumAdapter)this.mRecyclerView.GetAdapter()).ResetValues();  
                    });  
                });  
            };  
    

    And in your Adapter

        public void ResetValues()  
        {  
            mPhotoAlbum.ForEach((td) => { td.mCaption = "updated data"; });  
            //this.NotifyAll();  
            NotifyDataSetChanged();  
        }  
    

    Best Regards,

    Jessie Zhang


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our [documentation][3] to enable e-mail notifications if you want to receive the related email notification for this thread. [3]: https://learn.microsoft.com/en-us/answers/articles/67444/email-notifications.html


0 additional answers

Sort by: Most helpful