Skip to content

Instantly share code, notes, and snippets.

@DevSrSouza
Last active November 29, 2020 18:32
Show Gist options
  • Save DevSrSouza/f5c3967f0e234ced0ab31f7158ae827e to your computer and use it in GitHub Desktop.
Save DevSrSouza/f5c3967f0e234ced0ab31f7158ae827e to your computer and use it in GitHub Desktop.
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
typealias InflateBindingCallback<BINDING> = (LayoutInflater, ViewGroup, viewType: Int) -> BINDING
typealias GetViewFromBindingCallback<BINDING> = (BINDING) -> View
typealias OnBindCallback<DATACLASS, BINDING> = (DATACLASS, BINDING, position: Int) -> Unit
typealias DataClassComparator<DATACLASS> = (oldItem: DATACLASS, newItem: DATACLASS) -> Boolean
typealias ItemViewType<DATACLASS> = (DATACLASS) -> Int
inline fun <DATACLASS : Any, BINDING : ViewBinding> KotlinListAdapter(
noinline inflateBinding: InflateBindingCallback<BINDING>,
noinline getViewFromBinding: GetViewFromBindingCallback<BINDING>,
noinline onBind: OnBindCallback<DATACLASS, BINDING>,
noinline isDataClassItemsTheSame: DataClassComparator<DATACLASS>,
noinline itemViewType: (DATACLASS) -> Int = { 0 }
) = KotlinListAdapter(
inflateBinding,
getViewFromBinding,
onBind,
isDataClassItemsTheSame,
{ old, new -> old.equals(new)},
itemViewType
)
class KotlinListAdapter<DATACLASS, BINDING : ViewBinding>(
val inflateBinding: InflateBindingCallback<BINDING>,
val getViewFromBinding: GetViewFromBindingCallback<BINDING>,
val onBind: OnBindCallback<DATACLASS, BINDING>,
val isDataClassItemsTheSame: DataClassComparator<DATACLASS>,
val isDataClassContentTheSame: DataClassComparator<DATACLASS>,
val itemViewType: ItemViewType<DATACLASS>
) : ListAdapter<DATACLASS, KotlinListAdapter.ViewHolder<DATACLASS, BINDING>>(
KotlinDiffCallback<DATACLASS>(
isDataClassItemsTheSame, isDataClassContentTheSame
)
) {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ViewHolder<DATACLASS, BINDING> {
return ViewHolder.from(
viewType,
parent,
inflateBinding,
getViewFromBinding,
onBind
)
}
override fun getItemViewType(position: Int): Int {
return itemViewType(getItem(position))
}
override fun onBindViewHolder(
holder: ViewHolder<DATACLASS, BINDING>,
position: Int
) {
holder.bind(getItem(position))
}
class ViewHolder<DATACLASS, BINDING> private constructor(
val binding: BINDING,
val getViewFromBinding: GetViewFromBindingCallback<BINDING>,
val onBind: OnBindCallback<DATACLASS, BINDING>
) : RecyclerView.ViewHolder(getViewFromBinding(binding)) {
fun bind(dataClass: DATACLASS) {
onBind(dataClass, binding, adapterPosition)
}
companion object {
fun <DATACLASS, BINDING> from(
viewType: Int,
parent: ViewGroup,
inflateBinding: InflateBindingCallback<BINDING>,
getViewFromBinding: GetViewFromBindingCallback<BINDING>,
onBind: OnBindCallback<DATACLASS, BINDING>
): ViewHolder<DATACLASS, BINDING> {
val inflater = LayoutInflater.from(parent.context)
val binding = inflateBinding(inflater, parent, viewType)
return ViewHolder(
binding,
getViewFromBinding,
onBind
)
}
}
}
class KotlinDiffCallback<DATACLASS>(
val isDataClassItemsTheSame: DataClassComparator<DATACLASS>,
val isDataClassContentTheSame: DataClassComparator<DATACLASS>
) : DiffUtil.ItemCallback<DATACLASS>() {
override fun areItemsTheSame(
oldItem: DATACLASS,
newItem: DATACLASS
) = isDataClassItemsTheSame(oldItem, newItem)
override fun areContentsTheSame(
oldItem: DATACLASS,
newItem: DATACLASS
) = isDataClassContentTheSame(oldItem, newItem)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment