Skip to content

Instantly share code, notes, and snippets.

@segunfamisa
Created September 26, 2019 09:11
Show Gist options
  • Save segunfamisa/716401e58ead9e6eb1c848a51451f927 to your computer and use it in GitHub Desktop.
Save segunfamisa/716401e58ead9e6eb1c848a51451f927 to your computer and use it in GitHub Desktop.
Delegated Properties for RecyclerView Adapters
class ObservableListField<T, VH : RecyclerView.ViewHolder>(
private val adapter: RecyclerView.Adapter<VH>,
private val diffUtilCallbackProducer: ((List<T>, List<T>) -> DiffUtil.Callback)?,
initialValue: List<T>
) : ObservableProperty<List<T>>(initialValue = initialValue) {
private var result: DiffUtil.DiffResult? = null
override fun beforeChange(
property: KProperty<*>,
oldValue: List<T>,
newValue: List<T>
): Boolean {
val diffUtilCallback = diffUtilCallbackProducer?.invoke(oldValue, newValue) ?: SimpleDiffUtilCallback(
oldItems = oldValue,
newItems = newValue
)
result = DiffUtil.calculateDiff(diffUtilCallback)
return true
}
override fun afterChange(property: KProperty<*>, oldValue: List<T>, newValue: List<T>) {
result?.dispatchUpdatesTo(adapter)
super.afterChange(property, oldValue, newValue)
}
/**
* Very simple diff util callback
*/
private inner class SimpleDiffUtilCallback<T> constructor(
private val oldItems: List<T>,
private val newItems: List<T>
) :
DiffUtil.Callback() {
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
oldItems[oldItemPosition] == newItems[newItemPosition]
override fun getOldListSize(): Int = oldItems.size
override fun getNewListSize(): Int = newItems.size
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
oldItems[oldItemPosition] == newItems[newItemPosition]
}
}
fun <T, VH : RecyclerView.ViewHolder> RecyclerView.Adapter<VH>.observableList(
initialValue: List<T>,
diffUtilCallbackProducer: ((List<T>, List<T>) -> DiffUtil.Callback)? = null
): ObservableProperty<List<T>> {
return ObservableListField(
adapter = this,
diffUtilCallbackProducer = diffUtilCallbackProducer,
initialValue = initialValue
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment