I'm attempting to implement a generic RV Adapter, mostly inspired by THIS COMMENT:
The code:
class RVAdapter <T: Any, VB: ViewBinding>(
private var dataSet: List<T>,
private val bindingInterface: RVBinding<T, VB>
) : ListAdapter<T, RVAdapter<T, VB>.RVHolder>(DiffCallback<T>()) {
inner class RVHolder(private val binding: ViewBinding): RecyclerView.ViewHolder(binding.root) {
fun<T: Any, VB: ViewBinding> bind(item: T, bindingInterface: RVBinding<T, VB>) {
bindingInterface.bind(item, (binding as VB)) //3: unchecked cast
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RVHolder {
val binding = (VB as ViewBinding).inflate() //1: how do you inflate from generic VB?
return RVHolder(binding)
}
override fun onBindViewHolder(holder: RVHolder, position: Int) {
holder.bind(getItem(position), bindingInterface)
}
override fun getItemCount() = dataSet.size
}
private class DiffCallback<T: Any>: DiffUtil.ItemCallback<T>() {
//2: how do you implement the following two methods?
override fun areItemsTheSame(oldItem: T, newItem: T): Boolean {
TODO("Not yet implemented")
}
override fun areContentsTheSame(oldItem: T, newItem: T): Boolean {
return oldItem == newItem
}
}
interface RVBinding<T: Any, VB: ViewBinding> {
fun bind(item: T, binding: VB)
}
I'm facing two main problems:
- how do I inflate the binding in
onCreateViewHolder()
? Normally, I useSpecificBinding.inflate()
but that doesn't seem to work with a generic view binding. - how would I implement the
DiffUtil
portion in a generic way? Sure, I could compareold.toString == new.toString
but that's not generic. AlsooldItem == newItem
doesn't haveequals()
implemented.
So how would I solve these problems in a way to make the Adapter as generic as possible? And any other suggestions would be welcome.
For example, you can use the generic structure below.
GenericDiffUtil.kt