Last active
July 19, 2021 01:59
-
-
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
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
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() | |
} | |
} |
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
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!