简体   繁体   English

RecyclerView.Adapter notifyItemChanged()与异步网络更新?

[英]RecyclerView.Adapter notifyItemChanged() with async network update?

I have a RecyclerView using a LinearLayoutManager, and a custom RecyclerView.Adapter. 我有一个使用LinearLayoutManager的RecyclerView和一个自定义的RecyclerView.Adapter。 When a user long-clicks an item, it triggers an asynchronous network refresh of only that item. 当用户长按某个项目时,它会触发仅对该项目进行异步网络刷新。 I know the item's position at the time of the long-click, and I can pass that position on to the network refreshing function. 我知道项目在长按时的位置,我可以将该位置传递给网络刷新功能。 However by the time the refresh is complete and notifyItemChanged() is called, the user may have added a new item or removed one. 但是,当刷新完成并且notifyItemChanged() ,用户可能已添加新项目或已删除项目。 So while the refreshed item may have originated from position 4, by the time the refresh is done it could be in 3 or 5 or somewhere else. 因此,虽然刷新的项目可能源自位置4,但是在刷新完成时它可以在3或5或其他地方。

How can I ensure that I call notifyItemChanged() with the right position parameter? 如何确保使用正确的位置参数调用notifyItemChanged()

Here are three possible solutions: 这有三种可能的解决方案:

  1. Call notifyDataSetChanged() instead and call it a day. 改为调用notifyDataSetChanged()并将其调用一天。

  2. Keep a separate map of items by a unique ID in your adapter. 通过适配器中的唯一ID保留单独的项目映射。 Have the network refresh return item along with the unique ID. 让网络刷新返回项目以及唯一ID。 Access the item through the ID map and figure out its position. 通过ID地图访问该项目并找出其位置。 Obviously if there is no unique ID for your items, this isn't an option. 显然,如果您的商品没有唯一ID,则不能选择此选项。

  3. Keep track of the item(s) being refreshed. 跟踪正在刷新的商品。 Register your own AdapterDataObserver and track all the inserts and updates, calculating the new position of the item each time and saving it until refresh returns. 注册您自己的AdapterDataObserver并跟踪所有插入和更新,每次计算项目的新位置并保存直到刷新返回。

While notifyDataSetChanged() will do the trick, if it is essential to know the position of the item, you can always go with implementation of hashCode and equals in the model class of the list item used in recyclerview adapter. 虽然notifyDataSetChanged()可以解决这个问题,但是如果知道项目的位置是必不可少的,那么你总是可以在recyclerview适配器中使用的列表项的模型类中实现hashCode和equals。

Implement hashcode and equals method to get the position for the required model object. 实现hashcode和equals方法以获取所需模型对象的位置。

Example : 示例:

public class Employee {
    protected long   employeeId;
    protected String firstName;
    protected String lastName;

    public boolean equals(Object o){
    if(o == null)                return false;
    if(!(o instanceof) Employee) return false;

    Employee other = (Employee) o;
    if(this.employeeId != other.employeeId)      return false;
    if(! this.firstName.equals(other.firstName)) return false;
    if(! this.lastName.equals(other.lastName))   return false;

    return true;
  }

  public int hashCode(){
    return (int) employeeId;
  }
}

// To get the index of selected item which triggered async task :
int itemIndex = EmployeeList.indexOf(selectedEmployeeModel);
recyclerView.scrollToPosition(itemIndex);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM