Created
September 26, 2019 09:11
-
-
Save segunfamisa/716401e58ead9e6eb1c848a51451f927 to your computer and use it in GitHub Desktop.
Delegated Properties for RecyclerView Adapters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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