0

我有 2 列RecyclerView基于StaggeredGridLayoutManager.

当更改第 1 项的内容并触发DiffUtilRecyclerView 时,会跳转到第 2 项。但是当向上滚动时,可能会看到 1 个元素和空白空间,在滚动期间项目正在转换为自然顺序。此外,差异列表中的项目数量是相同的。

如何避免这种烦人的行为并在 diffUtil 期间保持滚动位置?

val layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
    recyclerView.layoutManager = layoutManager
    recyclerView.itemAnimator = null
    recyclerView.setHasFixedSize(true)
    recyclerView.setItemViewCacheSize(if (App.isTablet()) 3 else 2)

public void diffUpdate(List<T> newList) {
    if (getCollection().size() == 0) {
      addAll(newList);
      notifyDataSetChanged();
    } else {
      DiffCallback diffCallback = new DiffCallback<T>(getCollection(), newList);
      DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallback);
      clear();
      addAll(newList);
      diffResult.dispatchUpdatesTo(this);
    }
  }
4

1 回答 1

0

问题在于 DiffCallback 的实现。之前我使用了哈希:

    @Override public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
      T oldItem = oldList.get(oldItemPosition);
      T newItem = newList.get(newItemPosition);
      boolean areTheSameInstance = oldItem == newItem;
      boolean hasTheSameType = oldItem.getClass().equals(newItem.getClass());
      boolean hasTheSameHash = oldItem.hashCode() == newItem.hashCode();
      return areTheSameInstance || hasTheSameType && hasTheSameHash;
    }

这触发了 RecyclerView 中整个视图的重新创建,并可能在 StaggeredGridLayoutManager 中进行测量。

在我将其更改为 id check 后,diffCalbback 已开始仅触发 RecyclerView 中视图的呈现。

return ((Model) oldItem).id() == ((Model) newItem).id();
于 2017-12-18T13:57:42.820 回答