I created a RecyclerView Adapter using databinding and I'm trying to handle Click events inside this adapter but I don't know exactly how. I found different topics but couldn't solve my problem yet. Thanks! Where should I implement (inside the Adapter class) the onClick function?
Adapter Class
class RemovableContactsAdapter(val viewModel: GroupDetailsViewModel,val callback:GroupContactsCallback) : RecyclerView.Adapter<RemovableContactsViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RemovableContactsViewHolder {
val binding: ViewDataBinding =
DataBindingUtil.inflate(LayoutInflater.from(parent.context), viewType, parent, false)
return RemovableContactsViewHolder(binding)
}
override fun onBindViewHolder(holder: RemovableContactsViewHolder, position: Int) {
holder.bind(viewModel, callback, position)
}
override fun getItemCount(): Int {
return viewModel.currentGroup.value?.contacts?.size ?: 0
}
override fun getItemViewType(position: Int): Int {
return R.layout.removable_contact_layout
}
}
class RemovableContactsViewHolder(val binding: ViewDataBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(viewModel: GroupDetailsViewModel, callback: GroupContactsCallback, position: Int) {
binding.root.selected_contact_iv.apply {
visibility = if (viewModel.currentGroup.value?.contacts!![position].selected) {
View.VISIBLE
} else {
View.GONE
}
}
binding.setVariable(BR.contact, viewModel.currentGroup.value?.contacts?.get(position))
binding.setVariable(BR.callback, callback)
binding.executePendingBindings()
}
}
Callback interface in Fragment class:
interface GroupContactsCallback {
fun selectContact(contact: ContactModel)
}
EDIT
I updated the bind function inside RemovableContactsViewHolder but still not working.
class RemovableContactsViewHolder(val binding: ViewDataBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(viewModel: GroupDetailsViewModel, callback: GroupContactsCallback, position: Int) {
itemView.setOnClickListener {
viewModel.currentGroup.value?.contacts?.get(position)!!.selected = !viewModel.currentGroup.value?.contacts?.get(position)!!.selected
callback.selectContact(viewModel.currentGroup.value?.contacts?.get(position)!!)
}
binding.root.selected_contact_iv.apply {
visibility = if (viewModel.currentGroup.value?.contacts!![position].selected) {
View.VISIBLE
} else {
View.GONE
}
}
binding.setVariable(BR.contact, viewModel.currentGroup.value?.contacts?.get(position))
binding.setVariable(BR.callback, callback)
binding.executePendingBindings()
}
It is not a good practice to handle click inside your adapter. And don't use interface just for this. Use this instead.
class YourRecyclerViewAdapter(private val onSelect: (YourDataType?) -> Unit) : RecyclerView.Adapter<YourRecyclerViewAdapter.YourViewHolder>() {
override fun onBindViewHolder(holder: YourViewHolder, position: Int) {
holder.bind(getItem(position), onSelect)
}
class ViewHolder(private val binding: YourViewBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(yourDataType: YourDataType?, onSelect: (YourDataType?) -> Unit) {
// bind your view here
binding.root.setOnClickListener {
onSelect(yourDataType)
}
}
}
}
In your Fragment/Activity
// Set this adapter to your recycler view
val adapter = YourRecyclerViewAdapter { yourDataType->
// Handle click here
}