【问题标题】:DiffUtil not calling onBindView or refreshing ViewHolderDiffUtil 未调用 onBindView 或刷新 ViewHolder
【发布时间】:2021-02-21 15:31:36
【问题描述】:

我尝试使用 DiffUtil 方法更新我的列表,该列表始终包含 30 个项目,现在每个项目数据每分钟更新一次,但无法判断所有项目的数据是否都会更新,以避免滥用 notifyDataSetChanged() 我创建了一个类扩展 DiffUtil。

public class DifUtil extends DiffUtil.Callback {

private final List<Asset> oldList, newList;

public DifUtil(List<Asset> newList, List<Asset> oldList) {
    this.oldList = oldList;
    this.newList = newList;
}

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

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

@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
    return oldList.get(oldItemPosition).getId().equals(newList.get(newItemPosition).getId());
}

@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
    return oldList.get(oldItemPosition).equals(newList.get(newItemPosition));
}

@Nullable
@Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
    //you can return particular field for changed item.
    return super.getChangePayload(oldItemPosition, newItemPosition);
}

}

添加新的公共函数来通知适配器

public void updateList(List<Asset> newList) {
    DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DifUtil(newList, this.assetList));
    this.assetList.clear();
    this.assetList.addAll(newList);
    diffResult.dispatchUpdatesTo(this);
}

覆盖另一个onBindViewHolder(不使用payload时不确定是否需要)

onBindViewHolder(@NonNull AssetsAdapter.ViewHolder holder, int position, @NonNull List<Object> payloads)

然后通过调用来更新列表

adapter.updateList(newAssetList);

列表的更新有效,但我只能通过滚动列表来查看这些新值,即使不回收视图(滚动时)我也需要查看更新,就像 notifyItemChanged() 一样。

据我了解,调用 dispatchUpdatesTo 应该处理和更新视图及其数据,或者我在这里遗漏了什么,请赐教。

【问题讨论】:

  • 您必须复制assetList 作为diffutil 参数。这有点违反直觉,但不是整个逻辑在calculateDiff 期间完成,如果您修改任何作为参数传递的列表dispatchUpdatesTo 可能会失败。如果您不生成和处理有效负载,也不要覆盖 3 参数 onBindViewHolder
  • @Pawel 有效载荷的用途是什么?当数据集发生变化时,您可能想要传递一些额外的数据,这意味着它是完全可选的吗?
  • 您可以使用它来执行已布局的视图的部分更新:stackoverflow.com/questions/33176336/…

标签: java android android-recyclerview android-diffutils


【解决方案1】:

我通过关注此博客及其实现 DiffUtil 的方式设法使其工作。 https://www.journaldev.com/20873/android-recyclerview-diffutil

但是我没有执行克隆部分,因为它与我的情况无关。

奖金 有一个已知错误,更新会使列表在底部滚动。我通过使用LayoutManager 保存滚动状态来摆脱这个问题,就像在这个 SO 答案中一样。

https://stackoverflow.com/a/44053550/11338467

所以我的适配器 DiffUtil 更新部分就是这个

public void updateList(List<Asset> newList) {
    Parcelable recyclerViewState = layoutManager.onSaveInstanceState();
    DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DifUtil(newList, this.assetList));
    diffResult.dispatchUpdatesTo(this);
    this.assetList.clear();
    this.assetList.addAll(newList);
    layoutManager.onRestoreInstanceState(recyclerViewState);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-11
    • 1970-01-01
    • 2021-11-07
    • 1970-01-01
    • 2013-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多