Skip to content

Leifzhang/DiffUtils

Repository files navigation

DiffUtils

背景以及原理

谷歌在封装RecyclerView时候建议我们最好不要去调用notifyDataSetChanged,而是去调用其他的局部刷新的方法(增删改)。但是由于要计算游标等等所以感觉其实非常不好用,而且可能会导致一些奇奇怪怪的crash问题。

而DiffUtils的使用,首先要有两个List,一个代表旧数据,一个代表新数据,内部旧涉及到数据copy的问题,如果浅拷贝的话,其equals比较是没有任何意义的,所以项目使用了深拷贝的形式。

原理基于Parcel,用安卓原生的Parcelable进行数据模型拷贝。

当前项目简单的diffutil封装以及配合recyclerview adapter使用,可以实现数据动态增删移动等等操作同时配合,recyclerview adapter的局部数据调整刷新结合在一起。

使用

代码已经加入了线程池,以及主线程调度逻辑,所以可以直接子线程使用。不上传maven的原因是觉得可能还不够完善,可以直接考虑代码复制。

  1. 对代码进行了重定义封装,当你需要使用深拷贝的时候,切记实现Parcelable接口,数据model最好实现IDifference接口,根据这个进行数据ID逻辑判断。如果要做内容比较的情况下实现IEqualsAdapter,同时使用插件生成hashcode,equals方法。
data class TestEntity(var id: Int = 0,
                      var displayTime: Long = 0,
                      var text: String? = Random().nextInt(10000).toString()) : Parcelable, IDifference, IEqualsAdapter {

    override val uniqueId: String
        get() = id.toString()

    fun update() {
        displayTime = System.currentTimeMillis()
        text = "更新数据"
    }

    constructor(source: Parcel) : this(
            source.readInt(),
            source.readLong(),
            source.readString()
    )

    override fun describeContents() = 0

    override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
        writeInt(id)
        writeLong(displayTime)
        writeString(text)
    }

    companion object {
        @JvmField
        val CREATOR: Parcelable.Creator<TestEntity> = object : Parcelable.Creator<TestEntity> {
            override fun createFromParcel(source: Parcel): TestEntity = TestEntity(source)
            override fun newArray(size: Int): Array<TestEntity?> = arrayOfNulls(size)
        }
    }
}
  1. 初始化并传入数据,并设置数据刷新回掉,如果你有header或者别的话自己定义一个,提供了深拷贝和浅拷贝的两种实现。
     // 深拷贝
     val diffHelper: ParcelDiffHelper<TestEntity> = ParcelDiffHelper()
     diffHelper.callBack = SimpleAdapterCallBack(this)
     // lifecyclerowner 
     diffHelper.bindLifeCycle(this)
     diffHelper.setData(items)
    //浅拷贝版本
     val diffHelper: SimpleDiffHelper<String> = SimpleDiffHelper()
     diffHelper.callBack = SimpleAdapterCallBack(this)
     // lifecyclerowner 
     diffHelper.bindLifeCycle(this)
     diffHelper.setData(items)
  1. 当items发生变化(任意变化增删改都行),调用数据刷新。
   diffHelper.notifyItemChanged()

其他

代码可以结合任意的Adapter使用,包括BRVH等等。Demo中有简单的接入方式。

About

通过Parcel copy的方式深copy数据 DiffUtil抽象

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy