问题描述
嘿,基本上我最近遇到了 RecyclerView
的问题(这里描述了我遇到的问题:RecyclerView recreating ViewHolder instead of rebinding)。我发现 ItemAnimator
中的 RecyclerView
决定了更改的 ViewHolder
是必须重新弹回还是应该创建和淡入淡出新的 ViewHolder。
这篇文章解释了一些事情: https://medium.com/android-news/anatomy-of-recyclerview-part-1-a-search-for-a-viewholder-continued-d81c631a2b91
我假设这是 DefaultItemAnimator 的一部分,它决定了应该发生什么:
/**
* {@inheritDoc}
* <p>
* If the payload list is not empty,DefaultItemAnimator returns <code>true</code>.
* When this is the case:
* <ul>
* <li>If you override {@link #animateChange(RecyclerView.ViewHolder,RecyclerView.ViewHolder,int,int)},both
* ViewHolder arguments will be the same instance.
* </li>
* <li>
* If you are not overriding {@link #animateChange(RecyclerView.ViewHolder,* then DefaultItemAnimator will call {@link #animateMove(RecyclerView.ViewHolder,int)} and
* run a move animation instead.
* </li>
* </ul>
*/
@Override
public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder,@NonNull List<Object> payloads) {
return !payloads.isEmpty() || super.canReuseUpdatedViewHolder(viewHolder,payloads);
}
现在我的问题的解决方案是使用一些任意负载调用 onItemRangeChanged()
,它总是会重用 ViewHolder
。
我的问题:
现在我想知道为什么以及何时重新创建整个 ViewHolder
并使其淡入淡出比仅仅更新它的特定部分更好?在上面提到的交叉引用问题中,我只是改变了 ViewHolder 一小部分的可见性,但整个事情都被重新创建了,我认为这在性能方面会更差吗?
解决方法
请记住,RecyclerView
可以有多个项目视图类型。当 notifyItemChanged
导致视图类型更改时,无论负载如何,视图持有者都没有资格重用。
在这种情况下,动画师通过替换 viewholders 保持统一的行为。
此外,通过更新 ViewHolder,它们不会经历人们在布置新项目时可能期望的适配器 onViewAttachedToWindow(holder)
以及为正在删除的项目调用的 onViewRecycled(holder)
& onViewDetachedFromWindow(holder)
.
附带说明,如果您在后续范围更新(没有有效负载)期间遇到 onCreateViewHolder
调用,您可能应该增加 RecyclerView.RecycledViewPool
的大小。