RecyclerView和DiffUtil 性能优化

旧巷老猫 提交于 2021-02-17 16:36:28

DiffUtil 谷歌工具 为了解决部分或者极少数据源改变时,避免Adapter调用notifyDataSetChanged无脑全部刷新,消耗性能,而且刷新太死交互不友好.

 

RecyclerView 其实有自带数据源改变效果,但是需要知道变化所在的position,麻烦

adapter.notifyItemRangeInserted(position, count); 通知更新数据插入

adapter.notifyItemRangeRemoved(position, count); 通知更新数据移出

adapter.notifyItemMoved(fromPosition, toPosition);通知更新数据位置更换
adapter.notifyItemRangeChanged(position, count, payload);通知更新数组改变

DiffUtil 优点 就是它对新老数据的进行对比,再计算变动情况,配合RecyclerView.Adapter进行局部更新

DiffUtil使用类

 DiffUtil.Callback 对新来数据进行判断

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.util.DiffUtil;
import android.text.TextUtils;

import com.ryjf.customer.b.lighthouse.LightBean;

import java.util.List;

/**
 * 曝光台 新老数据对比
 * Created by Administrator on 2019/1/4.
 */

public class ItemDiffCallBack extends DiffUtil.Callback {
    private List<LightBean> mOldList;
    private List<LightBean> mNewList;

    public ItemDiffCallBack (List<LightBean> oldList, List<LightBean> newList) {
        this.mNewList = newList;
        this.mOldList = oldList;
    }

    @Override
    public int getOldListSize() {
        return mOldList == null ? 0 : mOldList.size();
    }

    @Override
    public int getNewListSize() {
        return mNewList == null ? 0 : mNewList.size();
    }

    //判断是否是同一个对象,是否来自同一个布局ViewType
    @Override
    public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
        return mOldList.get(oldItemPosition).getClass() == mNewList.get(newItemPosition).getClass();
    }

    //对象相同,再进一步判断相同对象的内容是否相同
    @Override
    public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
        String oldContent = mOldList.get(oldItemPosition).getContent();
        String newContent = mNewList.get(newItemPosition).getContent();
        return TextUtils.equals(oldContent, newContent);
    }

    //内容不同时,getChangePayload会记录下来,通知Adapter更新
    @Nullable
    @Override
    public Object getChangePayload(int oldItemPosition, int newItemPosition) {
        LightBean oldBean = mOldList.get(oldItemPosition);
        LightBean newBean = mNewList.get(newItemPosition);
        Bundle diffBundle = new Bundle();
        if (!TextUtils.equals(oldBean.getContent(), newBean.getContent())) {
            diffBundle.putString("content", newBean.getContent());
        }
        return diffBundle;
    }
}

 DiffUtil.DiffResult 对比返回结果集

DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new ItemDiffCallBack(mOldList, mNewList));
diffResult.dispatchUpdatesTo(adapter);

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!