Skip to content

Instantly share code, notes, and snippets.

@timfreiheit
Created June 14, 2019 11:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timfreiheit/8af66787b7e867b4fcc4055171ef0814 to your computer and use it in GitHub Desktop.
Save timfreiheit/8af66787b7e867b4fcc4055171ef0814 to your computer and use it in GitHub Desktop.
MultiTypeDiffItemCallback
class MultiTypeDiffItemCallback<T: Any> : DiffUtil.ItemCallback<T>() {
private val itemCallbacks = mutableMapOf<Any, DiffUtil.ItemCallback<T>>()
fun <Subclass: T> register(clazz: Class<Subclass>, callback: DiffUtil.ItemCallback<Subclass>) {
@Suppress("UNCHECKED_CAST")
itemCallbacks[clazz] = callback as DiffUtil.ItemCallback<T>
}
override fun areItemsTheSame(oldItem: T, newItem: T): Boolean {
if (oldItem.javaClass != newItem.javaClass) {
return false
}
return itemCallbacks[oldItem.javaClass]
?.areItemsTheSame(oldItem, newItem)
?: (oldItem == newItem)
}
@SuppressLint("DiffUtilEquals")
override fun areContentsTheSame(oldItem: T, newItem: T): Boolean {
if (oldItem.javaClass != newItem.javaClass) {
return false
}
return itemCallbacks[oldItem.javaClass]
?.areContentsTheSame(oldItem, newItem)
?: (oldItem == newItem)
}
}
fun <T> simpleDiffItemCallback(
areItemsTheSame: (oldItem: T, newItem: T) -> Boolean = { oldItem, newItem -> oldItem == newItem },
areContentsTheSame: (oldItem: T, newItem: T) -> Boolean = { oldItem, newItem -> oldItem == newItem }
): DiffUtil.ItemCallback<T> {
return object : DiffUtil.ItemCallback<T>() {
override fun areItemsTheSame(oldItem: T, newItem: T): Boolean {
return areItemsTheSame(oldItem, newItem)
}
override fun areContentsTheSame(oldItem: T, newItem: T): Boolean {
return areContentsTheSame(oldItem, newItem)
}
}
}
open class SimpleDiffItemCallback<T> : DiffUtil.ItemCallback<T>() {
override fun areItemsTheSame(oldItem: T, newItem: T): Boolean {
return oldItem == newItem
}
@SuppressLint("DiffUtilEquals")
override fun areContentsTheSame(oldItem: T, newItem: T): Boolean {
return oldItem == newItem
}
}
class SyncDiffItemCallback<T>(
private val oldList: List<T>,
private val newList: List<T>,
private val itemCallback: DiffUtil.ItemCallback<T>
) : DiffUtil.Callback() {
override fun getOldListSize() = oldList.size
override fun getNewListSize() = newList.size
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return itemCallback.areItemsTheSame(oldList[oldItemPosition], newList[newItemPosition])
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return itemCallback.areContentsTheSame(oldList[oldItemPosition], newList[newItemPosition])
}
}
val result = DiffUtil.calculateDiff(
SyncDiffItemCallback(
oldList = field,
newList = value,
itemCallback = MultiTypeDiffItemCallback<Any>().apply {
register(Item::class.java, simpleDiffItemCallback(
areItemsTheSame = { item1, item2 -> item1.id == item2.id }
))
}
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment