Skip to content

Instantly share code, notes, and snippets.

@jermainedilao
Last active July 19, 2021 01:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jermainedilao/f7002e41f53bd601a3edd1437f498254 to your computer and use it in GitHub Desktop.
Save jermainedilao/f7002e41f53bd601a3edd1437f498254 to your computer and use it in GitHub Desktop.
Powerful and Reusable ListAdapter for Simple Lists. For more info, check this article: https://medium.com/swlh/powerful-and-reusable-listadapter-using-databinding-for-simple-lists-55ac377fa750
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
class SimpleListAdapter<T : Any, B : ViewDataBinding>(
diffUtil: DiffUtil.ItemCallback<T>,
@LayoutRes private val layoutId: Int,
private val itemClickListener: (T) -> Unit
) : ListAdapter<T, ViewHolder<B>>(diffUtil) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder<B> {
return ViewHolder<B>(
DataBindingUtil.inflate(
LayoutInflater.from(parent.context),
layoutId,
parent,
false
)
).apply {
binding
.root
.findViewById<View>(R.id.itemClickable)
.setOnClickListener {
itemClickListener.invoke(getItem(adapterPosition))
}
}
}
override fun onBindViewHolder(holder: ViewHolder<B>, position: Int) {
holder.bind(getItem(position))
}
}
open class ViewHolder<B : ViewDataBinding>(val binding: B) : RecyclerView.ViewHolder(binding.root) {
fun bind(item: Any) {
binding.setVariable(BR.item, item)
binding.executePendingBindings()
}
}
@smoralb
Copy link

smoralb commented Jul 17, 2021

Hi! It seems good, but what about different items? I meam, if I have items like header, items of the list, separators, footer... . How can I adapt this adapter to this case?.

For this I have created a sealed class that contains every class or object that should be added to the list, but I have a problem with the DiffUtils, I should implement for every item, as each item have different attributes (not every one has id or any attribute) but I cannot find the solution for this. Do you have any idea?

This is my project where I define the BaseAdapter and BaseViewHolder

And this is how I am using in a SampleAdapter

As you can see, the DiffCallBack class should be the same for every item.

Hope hearing from you, Thanks!

@jermainedilao
Copy link
Author

Hi! Thanks for your response!

For headers & footers. I think the best and easiest way would be to use ConcatAdapter. Concat three of them (header, items, & footer adapters) before setting to the recyclerview.

For the separators, we can just use DividerItemDecoration or something similar.

If you have different item types in the list but they have the same ViewHolder. Then what you said with having a sealed class to compare would work.

Unfortunately, for lists that have different items AND different ViewHolder. We might not be able to use this one, since the goal for that article is for simple lists only.

I hope this helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment