diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/GenericRowAdapter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/GenericRowAdapter.kt index 2a26463c..9e52e4e8 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/GenericRowAdapter.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/GenericRowAdapter.kt @@ -16,16 +16,18 @@ import android.widget.ImageView import android.widget.PopupMenu import android.widget.RelativeLayout import android.widget.TextView +import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import org.moire.ultrasonic.R import org.moire.ultrasonic.data.ActiveServerProvider +import org.moire.ultrasonic.domain.GenericEntry import org.moire.ultrasonic.domain.MusicFolder import org.moire.ultrasonic.view.SelectMusicFolderView /* * An abstract Adapter, which can be extended to display a List of in a RecyclerView */ -abstract class GenericRowAdapter( +abstract class GenericRowAdapter( val onItemClick: (T) -> Unit, val onContextMenuClick: (MenuItem, T) -> Boolean, private val onMusicFolderUpdate: (String?) -> Unit @@ -40,11 +42,14 @@ abstract class GenericRowAdapter( var selectedFolder: String? = null /** - * Sets the data to be displayed in the RecyclerView + * Sets the data to be displayed in the RecyclerView, + * using DiffUtil to efficiently calculate the minimum required changes.. */ open fun setData(data: List) { + val callback = DiffUtilCallback(itemList, data) + val result = DiffUtil.calculateDiff(callback) itemList = data - notifyDataSetChanged() + result.dispatchUpdatesTo(this) } /** @@ -133,6 +138,27 @@ abstract class GenericRowAdapter( var coverArtId: String? = null } + /** + * Calculates the differences between data sets + */ + open class DiffUtilCallback( + private val oldList: List, + private val newList: List + ) : 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 { internal const val TYPE_HEADER = 0 internal const val TYPE_ITEM = 1