关键:public final void notifyItemChanged(int position, Object payload)
RecyclerView局部刷新大家都遇到过,有时候还说会遇见图片闪烁的问题。
优化之前的效果:
优化之后的效果:
如果想单独更新一个item,我们通常会这样做,代码如下:
mLRecyclerViewAdapter.notifyItemChanged(position);
这个也能达到更新的效果,但是有时候却美中不足。那么有没有更好的办法呢?通过查看api,我们发现了另一个方法:
/**
* Notify any registered observers that the item at <code>position</code> has changed with an
* optional payload object.
*
* <p>This is an item change event, not a structural change event. It indicates that any
* reflection of the data at <code>position</code> is out of date and should be updated.
* The item at <code>position</code> retains the same identity.
* </p>
*
* <p>
* Client can optionally pass a payload for partial change. These payloads will be merged
* and may be passed to adapter's {@link #onBindViewHolder(ViewHolder, int, List)} if the
* item is already represented by a ViewHolder and it will be rebound to the same
* ViewHolder. A notifyItemRangeChanged() with null payload will clear all existing
* payloads on that item and prevent future payload until
* {@link #onBindViewHolder(ViewHolder, int, List)} is called. Adapter should not assume
* that the payload will always be passed to onBindViewHolder(), e.g. when the view is not
* attached, the payload will be simply dropped.
*
* @param position Position of the item that has changed
* @param payload Optional parameter, use null to identify a "full" update
*
* @see #notifyItemRangeChanged(int, int)
*/
public final void notifyItemChanged(int position, Object payload) {
mObservable.notifyItemRangeChanged(position, 1, payload);
}
重点看payload参数介绍:
payload Optional parameter, use null to identify a "full" update
翻译过来就是如果payload参数是null,那么就会来一个“完整的”更新,也就是说会全部更新。
下面我们说一下具体怎么使用。
模拟更新一条数据:
int position = 1;//指定列表中的第2个item
ItemModel itemModel = mDataAdapter.getDataList().get(position);
itemModel.id = 100;
itemModel.title = "refresh item " + itemModel.id;
itemModel.imgUrl = "http://avatar.youkuaiyun.com/2/9/C/1_jdsjlzx.jpg";
mDataAdapter.getDataList().set(position,itemModel);
//RecyclerView局部刷新 详见:https://github.com/jdsjlzx/LRecyclerView/issues/45
// notifyItemChanged(int position, Object payload) 其中的payload相当于一个标记,类型不限
mLRecyclerViewAdapter.notifyItemChanged(mLRecyclerViewAdapter.getAdapterPosition(false,position) , position);
adapter中的onBindViewHolder方法:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
bind(holder,position);
}
//局部刷新关键:带payload的这个onBindViewHolder方法必须实现
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List payloads) {
TLog.error("onBindViewHolder payloads.isEmpty() ? " + payloads.isEmpty() );
if (payloads.isEmpty()) {
onBindViewHolder(holder,position);
} else {//需要更新的数据
TLog.error("onBindViewHolder payloads.size() = " + payloads.size());
//notifyItemChanged(int position, Object payload) 要与payload的类型保持一致
if (payloads.get(0) instanceof Integer) {
bind(holder,position);
}
}
}
上面代码说结合LRecyclerView框架来测试的,想要体验完整demo,请参考:https://github.com/jdsjlzx/LRecyclerView