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向上滑动一段距离然后再滑到底部才会显示更新的内容。

上一篇下一篇

猜你喜欢

热点阅读