Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Example adapter implementation with DiffUtil
abstract class DiffUtilAdapter<D, VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH>(), CoroutineScope {
override val coroutineContext = Dispatchers.Main.immediate
protected var dataset: List<D> = listOf()
private set
private val diffCallback by lazy(LazyThreadSafetyMode.NONE) { DiffCallback<D>() }
protected val detectMoves = true
private val updateActor = actor<List<D>>(capacity = Channel.CONFLATED) {
for (list in channel) internalUpdate(list)
protected abstract fun onUpdateFinished()
fun update (list: List<D>) {
private suspend fun internalUpdate(list: List<D>) {
val (finalList, result) = withContext(Dispatchers.Default) {
val finalList = list.toList()
val result = DiffUtil.calculateDiff(diffCallback.apply { update(dataset, finalList) }, detectMoves)
Pair(finalList, result)
dataset = finalList
override fun getItemCount() = dataset.size
fun isEmpty() = dataset.isEmpty()
open fun getItem(position: Int) = dataset[position]
class DiffCallback<D> : DiffUtil.Callback() {
lateinit var oldList: List<D>
lateinit var newList: List<D>
fun update(oldList: List<D>, newList: List<D>) {
this.oldList = oldList
this.newList = newList
override fun getOldListSize() = oldList.size
override fun getNewListSize() = newList.size
override fun areContentsTheSame(oldItemPosition : Int, newItemPosition : Int) = true
override fun areItemsTheSame(oldItemPosition : Int, newItemPosition : Int) = oldList[oldItemPosition] == newList[newItemPosition]

This comment has been minimized.

Copy link

@mochadwi mochadwi commented Aug 14, 2020

For simplicity as wrapper for DiffUtil adapter class use ListAdapter

But, if you wish for more control over adapter behavior, or to provide a specific base class should refer to AsyncListDiffer as stated in the official docs

Or use Paging library instead

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment