IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> DiffUtils使用流程 -> 正文阅读

[游戏开发]DiffUtils使用流程

DiffUtils是用来更新RecyclerView的工具,使用DiffUtils可以代替手动刷新RecyclerView。

使用方法

一、确定Item是否更新的规则(数据变化了,但是不一定需要更新UI界面)

创建一个类继承 DiffUtil.Callback ,重新四个abstract方法
class DiffCallBack(private val lastData: ArrayList<TestBean>, private val newData: ArrayList<TestBean>) :
    DiffUtil.Callback() {

    override fun getOldListSize(): Int {
        return lastData.size
    }

    override fun getNewListSize(): Int {
        return newData.size
    }

    /**
     * 用来判断是否是同一个item
     */
    override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        LogV("oldItemPosition = $oldItemPosition , newItemPosition = $newItemPosition")
        return lastData[oldItemPosition].name == newData[newItemPosition].name
    }

    /**
     * 只有 areItemsTheSame 为 True的时候才会调用这个方法
     * 用来判断是否UI需要改变
     */
    override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        LogV("oldItemPosition = $oldItemPosition , newItemPosition = $newItemPosition")
        return lastData[oldItemPosition] == newData[newItemPosition]
    }
}

二、计算新老数据集的差异,并且通知RecyclerView刷新

    //setDatas函数里面就不需要写notifyDataSetChanged()了,在数据更新的时候会重新走onbindView,只要数据是新的就行了。
    mAdapter.setDatas(newData)
    //计算新老数据集的差异
    val diffResult = DiffUtil.calculateDiff(DiffCallBack(oldData, newData), true)
    //通知RecyclerView刷新
    //推测是通过消息机制来刷新的,即使setDatas函数写在dispatchUpdatesTo后面, 也同样可以成功更新UI。
    diffResult.dispatchUpdatesTo(mAdapter)
使用dispatchUpdatesTo通知recyclerView刷新的时候,其实就是通过Adapter的定向刷新方法来更新数据的。
AdapterListUpdateCallback.class

    @Override
    public void onInserted(int position, int count) {
        mAdapter.notifyItemRangeInserted(position, count);
    }

    @Override
    public void onRemoved(int position, int count) {
        mAdapter.notifyItemRangeRemoved(position, count);
    }

    @Override
    public void onMoved(int fromPosition, int toPosition) {
        mAdapter.notifyItemMoved(fromPosition, toPosition);
    }

    @Override
    public void onChanged(int position, int count, Object payload) {
        mAdapter.notifyItemRangeChanged(position, count, payload);
    }

高阶用法,ViewHolder的局部刷新(究极节约资源大法)

比如一个ViewHolder里面有一个TV(TextView)跟一个IV(ImageView),IV 的图片链接没变化,TV的文字变化了,按照往常处理方法更新ViewHolder,通常是重走bindView方法,把ViewHolder里面的所有的View都重新赋值,但是使用DiffUtils的高阶用法之后,就可以只针对TV更新,不为IV重新设置图片链接了。

一 、在继承 DiffUtil.Callback的时候,重写getChangePayload方法

override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
    return super.getChangePayload(oldItemPosition, newItemPosition)
}
getChangePayload方法在areItemsTheSame 返回 true , areContentsTheSame返回false的时候调用,即 :新旧数据对应同一个Item,但是 content发生了变化,需要更新 部分或 全部 的UI。

二 、我们判断 那些 UI 绑定的数据发生变化了,然后记录下来,在返回值里面返回,可以使用Bundle或其它数据类型记录变化的数据。

  public Object getChangePayload(int oldItemPosition, int newItemPosition) {

        TestBean oldBean = mOldDatas.get(oldItemPosition);
        TestBean newBean = mNewDatas.get(newItemPosition);

        Bundle payload = new Bundle();
        if (!oldBean.getDesc().equals(newBean.getDesc())) {
            payload.putString("KEY_DESC", newBean.getDesc());
        }
        if (oldBean.getPic() != newBean.getPic()) {
            payload.putInt("KEY_PIC", newBean.getPic());
        }

        if (payload.size() == 0)//如果没有变化 就传空
            return null;
        return payload;
    }

三、重写RecyclerView里面的onBindViewHolder(DiffVH holder, int position, List payloads)方法,我们在getChangePayload 方法里的返回值就是 这个三参数 onBindViewHolder的第三个参数,我们根据哪些数据发生了变化,只更新对应的View即可,不需要重写给ViewHolder里面的View赋值了。

public void onBindViewHolder(DiffVH holder, int position, List<Object> payloads) {
        if (payloads.isEmpty()) {
            onBindViewHolder(holder, position);
        } else {
            Bundle payload = (Bundle) payloads.get(0);
            TestBean bean = mDatas.get(position);
            for (String key : payload.keySet()) {
                switch (key) {
                    case "KEY_DESC":
                        //这里可以用payload里的数据,不过data也是新的 也可以用
                        holder.tv2.setText(bean.getDesc());
                        break;
                    case "KEY_PIC":
                        holder.iv.setImageResource(payload.getInt(key));
                        break;
                    default:
                        break;
                }
            }
        }
    }

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-09-18 10:33:04  更:2021-09-18 10:33:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 13:47:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码