首页 > 解决方案 > Android RecyclerView DiffUtil.Callback: areContentsTheSame() 和 getChangePayload() 给出不同的比较结果

问题描述

DiffUtil.Callback 中有 2 个函数需要覆盖:

areContentsTheSame(int oldItemPosition, int newItemPosition)

getChangePayload(int oldItemPosition, int newItemPosition)

我知道前者检查内容是否已更改,我想通过直接使用'=='来简单地比较它们是否是同一个实例,因为我相信我的项目在更新时将是一个新实例。但是相同的比较在后一个函数中给出了不同的结果。这是代码:

public class MyDiffUtilCallback extends DiffUtil.Callback {
  List<App> mNewList;
  List<App> mOldList;

  public MyDiffUtilCallback(List<App> newList, List<App> oldList) {
    mNewList = newList;
    mOldList = oldList;
  }

  @Override
  public int getOldListSize() {
    return mOldList.size();
  }

  @Override
  public int getNewListSize() {
    return mNewList.size();
  }

  @Override
  public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
    return mNewList.get(newItemPosition).id == mOldList.get(oldItemPosition).id;
  }

  @Override
  public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
    return mNewList.get(newItemPosition) == mOldList.get(oldItemPosition);
    // This always returns false correctly whenever the item gets an update, it's working as expected
  }

  @Nullable
  @Override
  public Object getChangePayload(int oldItemPosition, int newItemPosition) {
    if (mNewList.get(newItemPosition) == mOldList.get(oldItemPosition)) {
      return null; // But this is always being executed
    }
    return mNewList.get(newItemPosition).data; // This is never executed, why?
  }
}

我不明白为什么旧项目和新项目之间的相同比较会给出不同的结果,是超类修改列表还是什么?

标签: javaandroidandroid-recyclerviewandroid-diffutils

解决方案


从Android定义

当 areItemsTheSame(int, int) 为两个项目返回 true 并且 areContentsTheSame(int, int) 为它们返回 false 时,DiffUtil 调用此方法以获取有关更改的有效负载。

您应该尝试更改以进行更详细的测试,而且我在Medium上找到了一篇不错的文章,它实现了getChangePayload. 我希望这对你有帮助。


推荐阅读