Use ListAdapter class to calculate Diff off the main thread

This commit is contained in:
tzugen 2021-06-20 08:24:14 +02:00
parent 1ecb577c50
commit 36dccc845b
No known key found for this signature in database
GPG Key ID: 61E9C34BC10EC930
2 changed files with 29 additions and 26 deletions

View File

@ -1,7 +1,19 @@
package org.moire.ultrasonic.domain package org.moire.ultrasonic.domain
abstract class GenericEntry { abstract class GenericEntry {
// TODO Should be non-null! // TODO: Should be non-null!
abstract val id: String? abstract val id: String?
open val name: String? = null open val name: String? = null
// These are just a formality and will never be called,
// because Kotlin data classes will have autogenerated equals() and hashCode() functions
override operator fun equals(other: Any?): Boolean {
return this === other
}
override fun hashCode(): Int {
var result = id?.hashCode() ?: 0
result = 31 * result + (name?.hashCode() ?: 0)
return result
}
} }

View File

@ -17,6 +17,7 @@ import android.widget.PopupMenu
import android.widget.RelativeLayout import android.widget.RelativeLayout
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import org.moire.ultrasonic.R import org.moire.ultrasonic.R
import org.moire.ultrasonic.data.ActiveServerProvider import org.moire.ultrasonic.data.ActiveServerProvider
@ -31,7 +32,8 @@ abstract class GenericRowAdapter<T : GenericEntry>(
val onItemClick: (T) -> Unit, val onItemClick: (T) -> Unit,
val onContextMenuClick: (MenuItem, T) -> Boolean, val onContextMenuClick: (MenuItem, T) -> Boolean,
private val onMusicFolderUpdate: (String?) -> Unit private val onMusicFolderUpdate: (String?) -> Unit
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { ) : ListAdapter<T, RecyclerView.ViewHolder>(GenericDiffCallback()) {
open var itemList: List<T> = listOf() open var itemList: List<T> = listOf()
protected abstract val layout: Int protected abstract val layout: Int
protected abstract val contextMenuLayout: Int protected abstract val contextMenuLayout: Int
@ -46,10 +48,8 @@ abstract class GenericRowAdapter<T : GenericEntry>(
* using DiffUtil to efficiently calculate the minimum required changes.. * using DiffUtil to efficiently calculate the minimum required changes..
*/ */
open fun setData(data: List<T>) { open fun setData(data: List<T>) {
val callback = DiffUtilCallback(itemList, data) submitList(data)
val result = DiffUtil.calculateDiff(callback)
itemList = data itemList = data
result.dispatchUpdatesTo(this)
} }
/** /**
@ -138,29 +138,20 @@ abstract class GenericRowAdapter<T : GenericEntry>(
var coverArtId: String? = null var coverArtId: String? = null
} }
/**
* Calculates the differences between data sets
*/
open class DiffUtilCallback<T : GenericEntry>(
private val oldList: List<T>,
private val newList: List<T>
) : DiffUtil.Callback() {
override fun getOldListSize(): Int {
return oldList.size
}
override fun getNewListSize(): Int {
return newList.size
}
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition].id == newList[newItemPosition].id
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition] == newList[newItemPosition]
}
}
companion object { companion object {
internal const val TYPE_HEADER = 0 internal const val TYPE_HEADER = 0
internal const val TYPE_ITEM = 1 internal const val TYPE_ITEM = 1
/**
* Calculates the differences between data sets
*/
class GenericDiffCallback<T : GenericEntry> : DiffUtil.ItemCallback<T>() {
override fun areContentsTheSame(oldItem: T, newItem: T): Boolean {
return oldItem == newItem
}
override fun areItemsTheSame(oldItem: T, newItem: T): Boolean {
return oldItem.id == newItem.id
}
}
} }
} }