美文网首页
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

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