【问题标题】:RecyclerView Adapter - NotifyItemRemoved - Removed item appears again after scrollRecyclerView 适配器 - NotifyItemRemoved - 滚动后再次出现已删除的项目
【发布时间】:2018-06-05 14:16:09
【问题描述】:

我认为我做错了,但我有一个 RecyclerView 适配器和简单的按钮单击(在本例中为 LinearLayout),它会触发以下操作

this.NotifyItemRemoved(position);

完整的按钮代码如下

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

这工作正常,项目被很好地移除,但是当我在recyclerview 中向下滚动并返回到项目被移除的位置时,项目又出现了。

我认为我做错了,或者我的逻辑不正确?有什么想法吗?

【问题讨论】:

  • NotifyItemRemoved 仅将其从显示器中删除(如果显示)并导致屏幕上其他元素的移动(动画),您还需要实际从适配器中删除支持数据正在存储它。
  • 哦,这就是我最初的想法,但我不认为我可以通过public override RecyclerView.ViewHolder OnCreateViewHolder 做到这一点?或者我是否必须在我将adapter 设置为RecyclerView.SetAdapter(adapter); 的片段中执行此操作?
  • @SushiHangover 你是个天才 :) 谢谢你,是的,我找到了根据你的 cmets 删除它的方法 - 你能把它写成答案,我会将其标记为已接受的答案:我使用.RemoveAt(index) 函数从实际的List 中删除了该项目,因为它是List
  • 我添加了一个答案,说明如何使用 ObservableCollection 完成所有 Notify*** 工作

标签: android xamarin android-recyclerview xamarin.android


【解决方案1】:

NotifyItemRemoved only 将其从显示中删除(如果显示或在其视图缓存中)并导致其他屏幕元素/视图的移动(动画),您还需要实际上从适配器中删除支持数据,但是您正在存储它。

例如,我有一个 RecyclerView.Adapter 子类,它将其数据作为 ObservableCollection&lt;SomeClass&gt; 存储在适配器内名为 myDataCollection 的实例变量中。

在适配器的初始化(对我来说是.ator)中,我在传递给构造函数的ObservableCollection 上注册了一个CollectionChanged 事件,即:

myDataCollection.CollectionChanged += CollectionChanged;

我的适配器子类中的那个事件被定义为:

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

现在每当我对ObservableCollection 进行更改时,适配器都会收到更改通知并更新它正在观察的RecyclerView

所以现在您可以让您更改添加/删除/移动到只是 ObservableCollectionRecyclerView 是“自动神奇地”更新。

如果您最终在适配器中使用 Filter 在您的 RecyclerView 中实现搜索功能,这也有效。

注意:如果ObservableCollection 中对象的属性发生变化,这不会更新 RecyclerView 中的膨胀视图,但如果需要,可以通过对象上的PropertyChangedEventHandler 来完成...

【讨论】:

  • 哇,这真是完美的解决方案 :) 谢谢你
  • @aliusman 没问题,它工作得非常好,也适用于Filter 工作,所以当您的搜索添加/删除/移动 ObservableCollection 中的项目时,recyclerview 会更新所有正确的动画 ;-)此外,如果您通过 ItemTouchHelper 在回收站视图中使用拖放操作。
  • 是的,这是完美的 :) 我没有使用“itemTouchHelper”,但在考虑使用它之后。仅供参考,我正在尝试为我的兴奋找到合适的表情符号,哈哈
  • 我唯一的改变是将 NotifyAll 替换为 NotifyDataSetChanged
猜你喜欢
  • 2017-09-06
  • 1970-01-01
  • 2020-05-06
  • 2016-10-26
  • 2020-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多