Last active
August 6, 2020 10:04
-
-
Save JavierSegoviaCordoba/3b01eb78e91d67b625966c1700927ac4 to your computer and use it in GitHub Desktop.
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
/** | |
* Usage: | |
* private val adapter by listAdapter(UserItemBinding::inflate, User::userId) { user: User -> | |
* textViewName.text = user.username | |
* imageView.load(user.avatarUrl) | |
* } | |
* @param [binding] is the item binding generated via ViewBinding or DataBinding | |
* @param [property] is the item property used by DiffUtil, if it is not indicated or it is null, DiffUtil will search | |
* for a property called id | |
* @param [onBind] is the lambda which include the item object | |
*/ | |
class BaseListAdapter<ITEM : Any, VB : ViewBinding>( | |
private val binding: (LayoutInflater, ViewGroup, Boolean) -> VB, | |
property: KProperty1<ITEM, *>? = null, | |
private val onBind: (VB.(ITEM) -> Unit) | |
) : ListAdapter<ITEM, BaseListAdapter<ITEM, VB>.BaseViewHolder>( | |
BaseDiff<ITEM>(property) | |
) { | |
private var onClick: ((ITEM, position: Int) -> Unit)? = null | |
fun onClick(listener: (ITEM, position: Int) -> Unit) { | |
onClick = { item, position -> listener(item, position) } | |
} | |
private var onLongClick: ((ITEM, position: Int) -> Unit)? = null | |
fun onLongClick(listener: (ITEM, position: Int) -> Unit) { | |
onLongClick = { item, position -> listener(item, position) } | |
} | |
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder { | |
return BaseViewHolder(binding.invoke(LayoutInflater.from(parent.context), parent, false)) | |
} | |
override fun onBindViewHolder(viewHolder: BaseViewHolder, position: Int) { | |
return viewHolder.bind(getItem(position)) | |
} | |
inner class BaseViewHolder(val binding: VB) : RecyclerView.ViewHolder(binding.root) { | |
fun bind(item: ITEM) { | |
with(binding) { | |
root.setOnClickListener { onClick?.invoke(item, adapterPosition) } | |
root.setOnLongClickListener { | |
onLongClick?.invoke(item, adapterPosition).run { true } | |
} | |
onBind.invoke(binding, item) | |
} | |
} | |
} | |
} | |
open class BaseDiff<T : Any>(private val property: KProperty1<T, *>?) : DiffUtil.ItemCallback<T>() { | |
override fun areItemsTheSame(old: T, new: T): Boolean { | |
val oldProperty = old::class.members.firstOrNull { it == property } | |
val newProperty = new::class.members.firstOrNull { it == property } | |
return if (oldProperty != null && newProperty != null) oldProperty == newProperty else false | |
} | |
@SuppressLint("DiffUtilEquals") | |
override fun areContentsTheSame(old: T, new: T): Boolean = old == new | |
} | |
inline fun <reified ITEM : Any, VB : ViewBinding> listAdapter( | |
noinline binding: (LayoutInflater, ViewGroup, Boolean) -> VB, | |
identifier: KProperty1<ITEM, *>? = null, | |
noinline onBind: VB.(ITEM) -> Unit | |
): Lazy<BaseListAdapter<ITEM, VB>> { | |
return lazy { BaseListAdapter(binding, identifier, onBind) } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment