我正在处理一个相当烦人的bug,其中notifyItemChanged()的多个(相同)调用有时只触发onBindViewHolder()。我这样称呼notifyItemChanged:
public void updateData(Data stuff) {
// Update data.
int index = findIndexOfChangedItem(stuff);
// Using or adding notifyDataSetChanged() doesn't help.
notifyItemChanged(index);
}
onBindViewHolder非常简单。
@Override
public void onBindViewHolder(MyItemViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder called for position " + position);
holder.setData(myList.get(position));
}
我观察到的问题是,当多次调用updateData() (有时频繁,在一秒钟内多次调用)时,一些更新将被删除。但是它确实经过了一半的时间,所以我知道基本的实现在某种程度上是可行的。
我已经查看了所有显而易见的事情,比如确保索引是正确的,并且notifyItemChanged()实际上正在被调用。另外,有趣的是,如果我添加我自己的自定义观察者:
private RecyclerView.AdapterDataObserver obs = new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
Log.d(TAG, "Observed state change in custom observer.");
super.onChanged();
}
};
我看到,自定义观察者每次都会触发,!
为什么有些时候会跳过回收视图. skipped的onBindViewHolder,有什么方法可以绕过它吗?
编辑
我不知道这是否是由于androidx.recyclerview.widget.AdapterHelper
的onItemRangeChanged
只返回true
,如果只有一件事需要更新:
/**
* @return True if updates should be processed.
*/
boolean onItemRangeChanged(int positionStart, int itemCount, Object payload) {
if (itemCount < 1) {
return false;
}
mPendingUpdates.add(obtainUpdateOp(UpdateOp.UPDATE, positionStart, itemCount, payload));
mExistingUpdateTypes |= UpdateOp.UPDATE;
return mPendingUpdates.size() == 1;
}
然后,如果我在一个已经挂起的更新中添加一个更新,则返回false
并删除我的更新。
发布于 2020-10-06 09:55:05
我遇到了同样的问题,并发现在notifyItemChanged
之后发生的onBindViewHolder
,但在绑定视图之前有机会实际附加在onViewAttachedToWindow
中是被删除的。IMO对数据的失效不应该依赖于视图状态--它是另一个(表示)层,所以它很可能是一个错误。
我在这里填充了一个bug:https://issuetracker.google.com/issues/170125522
我现在使用的解决方法是跟踪调用notifyItemChanged的视图,并在onViewAttachedToWindow
中签入(如果为此调用了onBindViewHolder
)。如果不是这样的话,就打电话给notifyItemChanged
。
https://stackoverflow.com/questions/60978038
复制相似问题