RecyclerView Adapter - NotifyItemRemoved - Removed item appears again after scroll

北慕城南 提交于 2019-12-24 17:13:24

问题


I think I am doing it all wrong, but I have a RecyclerView Adapter and simple button click (in this case a LinearLayout) which triggers the following

this.NotifyItemRemoved(position);

The full button code is the following

public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
..........
        LinearLayout _ARC = V.FindViewById<LinearLayout>(Resource.Id.moreArc);
        _ARC.Click += async delegate {
        try
        {
          Log.Info("101029", "ARC_Clicked");
          await usersAct.SWITCH_ARCHIVE(ID); // some user action
          this.NotifyItemRemoved(position);                   
        }
        catch (Exception X)
        {
          Log.Info("101029", "ERROR AT ARC_Clicked: " + X.Message);
        }
        };
.......
}

This works fine and the item gets removed nicely, but when I scroll down in the recyclerview and go back up to the position from where the item was removed, the item appears back.

I think I am doing it all wrong or my logic is not correct? Any idea?


回答1:


NotifyItemRemoved only removes it from the display (if displaying or in its view cache) and causes the moving (animation) of the other on-screen elements/views, you will also need to the actually remove the backing data from your adapter however you are storing it.

As an example, I have a RecyclerView.Adapter subclass that stores its data as an ObservableCollection<SomeClass> in an instance variable called myDataCollection within the adapter.

In the initialization of the adapter (the .ator for me), I register a CollectionChanged event on the ObservableCollection that I pass into the constructor, i.e.:

myDataCollection.CollectionChanged += CollectionChanged;

That event within my adapter subclass is defined as:

void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    switch (e.Action)
    {
        case NotifyCollectionChangedAction.Add:
            NotifyItemRangeInserted(e.NewStartingIndex, e.NewItems.Count);
            break;
        case NotifyCollectionChangedAction.Remove:
            NotifyItemRangeRemoved(e.OldStartingIndex, e.OldItems.Count);
            break;
        case NotifyCollectionChangedAction.Move:
            NotifyItemMoved(e.OldStartingIndex, e.NewStartingIndex);
            break;
        case NotifyCollectionChangedAction.Replace:
        case NotifyCollectionChangedAction.Reset:
            NotifyAll();
            break;
    }
}

Now anytime I make a change to the ObservableCollection, the adapter is notified of the change and updates the RecyclerView that is it observing.

So now you can make you changes adds/deletes/moves to just the ObservableCollection and the RecyclerView is "auto-magically" updated.

This also works if you end up using Filter within your adapter to implement a search feature in your RecyclerView.

Note: This does not update the inflated views within the RecyclerView if properties of the objects within the ObservableCollection change, but that can be done via PropertyChangedEventHandler on your objects if needed...



来源:https://stackoverflow.com/questions/50691177/recyclerview-adapter-notifyitemremoved-removed-item-appears-again-after-scro

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!