美文网首页
Recyclerview-Diffutils

Recyclerview-Diffutils

作者: Method | 来源:发表于2021-07-12 09:05 被阅读0次

是什么

DiffUtil是一个工具类,当你的RecyclerView需要更新数据时,将新旧数据集传给它,它就能快速告知adapter有哪些数据需要更新。就相当于如果改变了就对某个item刷新,没改变就没刷新,可以简称为局部刷新。

使用

/**
     * 当使用Diffutils的时候,这是一个计算2个list不同的回调函数
     */
    public abstract static class Callback {

        /**
         * 得到老的数据源大小
         */
        public abstract int getOldListSize();

        /**
         * 得到新的数据源大小
         */
        public abstract int getNewListSize();

        /**
         * 
         * 被DiffUtil调用,用来判断 两个对象是否是相同的Item。
         * 例如,如果你的Item有唯一的id字段,这个方法就判断id是否相等。
         */
        public abstract boolean areItemsTheSame(int oldItemPosition, int newItemPosition);

        /**
         * 用来检查 两个item是否含有相同的数据
         * 这个方法仅仅在areItemsTheSame()返回true时,才调用。
         */
        public abstract boolean areContentsTheSame(int oldItemPosition, int newItemPosition);
        /**
         * 当areItemsTheSame(int, int)返回true,且areContentsTheSame(int, int)返回false时,DiffUtils会回调此方法,
         * 去得到这个Item(有哪些)改变的payload。
         * 例如,如果你用RecyclerView配合DiffUtils,你可以返回  这个Item改变的那些字段,可以用那些信息去执行正确的动画
         * 返回 一个 代表着新老item的改变内容的 payload对象,
         */
        @Nullable
        public Object getChangePayload(int oldItemPosition, int newItemPosition) {
            return null;
        }
    }

Callback用来设置数据源的比较规则,判断新老数据之间的差异。

基础使用

Callback

package com.example.helloview.recyclerview.diffutils

import androidx.recyclerview.widget.DiffUtil

class UserCallBack(val oldList: List<UserBean>, val newList: List<UserBean>) :
    DiffUtil.Callback() {


    override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) =
        oldList[oldItemPosition].id == newList[newItemPosition].id

    override fun getOldListSize() = oldList.size
    override fun getNewListSize() = newList.size

    override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        val oldBean = oldList[oldItemPosition]
        val newBean = newList[newItemPosition]
        return oldBean.firstName == newBean.firstName && oldBean.lastName == newBean.lastName
    }
}

局部刷新

private fun diffData() {
        val newList = mutableListOf<UserBean>()
        val oldList = mutableListOf<UserBean>()
        newList.addAll(data)
        oldList.addAll(data)

        newList[2] = UserBean(20,"diff--","数据更新")
        val callback = UserCallBack(oldList,newList)

        //计算差异item
        val diffResult = DiffUtil.calculateDiff(callback,true)
         // 注意此处一定要将新数据设置给Adapter
         // 否则会造成ui刷新了但数据未更新的bug
        mAdapter?.setData(newList)
        //调用adapter的局部更新方法
        diffResult.dispatchUpdatesTo(mAdapter!!)
    }
  • 首先DiffUtil.calculateDiff()这个方法是执行在主线程的,如果新旧数据List比较大,那么这个方法铁定是会阻塞主线程的
  • 计算出DiffResult后,咱们必须要将新数据设置给Adapter,然后才能调用DiffResult.dispatchUpdatesTo(Adapter)刷新ui,然而很多人都会忘记这一步。
diff.gif

相关文章

  • Recyclerview-Diffutils

    是什么 DiffUtil是一个工具类,当你的RecyclerView需要更新数据时,将新旧数据集传给它,它就能快速...

网友评论

      本文标题:Recyclerview-Diffutils

      本文链接:https://www.haomeiwen.com/subject/bctlpltx.html