DiffUtil更新RecyclerView(深拷贝)
2020-06-10 本文已影响0人
竹叶儿青
一. 步骤
1. 实现DiffUtil.Callback
public class MovieDiffUtilCallback extends DiffUtil.Callback {
private List<MovieListBean.M> oldList;
private List<MovieListBean.M> newList;
public MovieDiffUtilCallback(List<MovieListBean.M> oldList, List<MovieListBean.M> newList) {
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) {
// 根据item的关键内容判断是否为同一个item
return oldList.get(oldItemPosition).getId() == newList.get(newItemPosition).getId();
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
// 判断同一个item的内容是否相同,仅在areItemsTheSame为true时调用
return oldList.get(oldItemPosition).getId() == newList.get(newItemPosition).getId();
}
// 比较得出应该更新的部分,仅在areItemsTheSame为true和areContentsTheSame为false时调用
@Nullable
@Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
return super.getChangePayload(oldItemPosition, newItemPosition);
}
}
2. 在RecyclerView的Adapter中重写onBindViewHolder(@NonNull MovieItemAndCastViewHolder holder, int position, @NonNull List<Object> payloads)
方法:
@Override
public void onBindViewHolder(@NonNull MovieItemAndCastViewHolder holder, int position, @NonNull List<Object> payloads) {
if (payloads.isEmpty()) {
onBindViewHolder(holder, position, payloads);
} else {
MovieListBean.M m = (MovieListBean.M) payloads.get(0);
holder.mainTitleTv.setText(m.getTitle());
}
}
当padloads为空,表示没有数据要更新,调用2个参数的onBindViewHolder(@NonNull MovieItemAndCastViewHolder holder, int position)
就行。
若不为空,则更新holder的内容。
3. 使用DiffResult更新数据
@Override
public void onMovieListDataSuccess(MovieListBean bean, int index) {
// deep copy list
List<MovieListBean.M> oldList = new ArrayList<>(mMovieList.size());
oldList.addAll(mMovieList);
mMovieList.addAll(bean.getResults());
DiffUtil.DiffResult result = DiffUtil.calculateDiff(new MovieDiffUtilCallback(oldList, mMovieList), false);
result.dispatchUpdatesTo(mAdapter);
}
这里new一个list用于存放旧的数据,然后addAll到oldList中,就是为了实现深拷贝的效果,如果直接令List<MovieListBean.M> oldList = mMovieList;mMovieList.addAll(bean.getResults());
,这是浅拷贝,更改后的mMovieList会影响到oldList,使得计算更新失效,刷新有问题。
我遇到的问题就是 浅拷贝导致更新有问题,需要把RecyclerView向上滑动一段距离然后再滑到底部才会显示更新的内容。