【问题标题】:Issue refreshing a view of a row in recyclerview在 recyclerview 中刷新一行视图的问题
【发布时间】:2016-02-16 05:09:45
【问题描述】:

我想在调用 notifyItemChanged 时更新 recyclerview 的视图。问题是我不想刷新整行,而只想刷新行的视图。 (避免行的闪烁效果)

有一个方法叫做 notifyItemChanged(int, payload obj)。

我可以用它来实现吗?如果可以怎么办?

【问题讨论】:

  • 你有没有尝试过?你能给我们看一些代码吗,比如你的 recyclerview 适配器?

标签: android android-recyclerview notifydatasetchanged


【解决方案1】:

最后我找到了如何只更新 RecyclerView 中一行的特定视图。

(1) 在适配器中重写 onBindViewHolder(Recycler.ViewHolder VH, int position, List payloads)

(2) 在 onBindViewHolder 方法内部,

if(payloads != null && !payloads.isEmpty() && (payloads.get(0) instanceof  customObject)){
   // update the specific view
}else{
   // I have already overridden  the other onBindViewHolder(ViewHolder, int)
   // The method with 3 arguments is being called before the method with 2 args. 
   // so calling super will call that method with 2 arguments. 
   super.onBindViewHolder(holder,position,payloads);
}

(3) 所以要通知数据变化和更新视图,需要调用notifyItemChanged(int position, Object payload)。需要将customObject(保存数据的模型)作为payload对象传递。

adapter.notifyItemChanged(i, obj);

注意:需要禁用 RecyclerView 的 ItemAnimator(默认启用)。否则有效载荷对象将为空。

recyclerView.setItemAnimator(null);

或

((SimpleItemAnimator)recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);

更新:我最近使用了这个方法,没有禁用 ItemAnimator。所以不需要禁用 ItemAnimator。 - (recyclerview-v7:25.4.0)

for further reference

【讨论】:

  • 非常好。这个问题让我很头疼,因为它创建了两个 ViewHolders,尽管我只想通过 notifiyItemChanged 更改一项。
  • 完美。这就是我想要的。
【解决方案2】:

您可以使用它来获取更新项目的视图:

View v = recyclerView.getLayoutManager().findViewByPosition(position);
if (v != null){
    //update your view
}

【讨论】:

    【解决方案3】:

    假设你有一个 ArrayList of items,它被馈送到 RecyclerView 适配器。让它变成这样。

    List<String> items = new ArrayList<>();
    RecyclerAdapter adapter = new RecyclerAdapter(items);
    recyclerView.setAdapter(adapter);
    

    现在我可以看到您想将项目插入 RecyclerView 并调用 notifyItemChanged(int position) 方法以仅添加单个项目。

    为此,假设您更改了位置 0 中项目的值。这是列表中的第一项。

    现在notifyItemChanged(int position)方法的正确用法是

    adapter.notifyItemChanged(0);
    

    这意味着,适配器将使用 0 位置的新值更新 recyclerview。

    【讨论】:

    • 不插入项目。我需要更改一个已经存在的数组列表项
    • 然后,不要调用 notifyItemInserted(int position),而是调用 notifyItemChaged(int position)。我已经更新了答案。
    • 是的,我已经这样做了。但它会刷新整行,导致闪烁效果。我想通过只刷新该行的特定视图来避免这种情况。
    • 你又在调用 setAdapter() 方法了吗?
    • 不,只需更改对象的布尔值并调用 notifyItemChanged。我对其进行了调试,它再次通过 onBindViewHolder 并再次将数据重置为视图。
    猜你喜欢
    • 2017-09-02
    • 2011-08-14
    • 1970-01-01
    • 2018-09-18
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    • 1970-01-01
    • 2017-06-20
    相关资源
    最近更新 更多