Can I use ViewBindings to replace findViewById
in this typical RecyclerView.Adapter
initialization code? I can't set a binding
val in the object as the ViewHolders are different per cell.
class CardListAdapter(private val cards: LiveData<List<Card>>) : RecyclerView.Adapter<CardListAdapter.CardViewHolder>() { class CardViewHolder(val cardView: View) : RecyclerView.ViewHolder(cardView) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardViewHolder { val binding = CardBinding.inflate(LayoutInflater.from(parent.context), parent, false) return CardViewHolder(binding.root) } override fun onBindViewHolder(holder: CardViewHolder, position: Int) { val title = holder.cardView.findViewById<TextView>(R.id.title) val description = holder.cardView.findViewById<TextView>(R.id.description) val value = holder.cardView.findViewById<TextView>(R.id.value) // ... }
To create a custom binding adapter, you need to create an extension function of the view that will use the adapter. Then, you add the @BindingAdapter annotation. You have to indicate the name of the view attribute that will execute this adapter as a parameter in the annotation.
What you need to do is pass the generated binding class object to the holder class constructor. In below example, I have row_payment
XML file for RecyclerView
item and the generated class is RowPaymentBinding
so like this
class PaymentAdapter(private val paymentList: List<PaymentBean>) : RecyclerView.Adapter<PaymentAdapter.PaymentHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PaymentHolder { val itemBinding = RowPaymentBinding.inflate(LayoutInflater.from(parent.context), parent, false) return PaymentHolder(itemBinding) } override fun onBindViewHolder(holder: PaymentHolder, position: Int) { val paymentBean: PaymentBean = paymentList[position] holder.bind(paymentBean) } override fun getItemCount(): Int = paymentList.size class PaymentHolder(private val itemBinding: RowPaymentBinding) : RecyclerView.ViewHolder(itemBinding.root) { fun bind(paymentBean: PaymentBean) { itemBinding.tvPaymentInvoiceNumber.text = paymentBean.invoiceNumber itemBinding.tvPaymentAmount.text = paymentBean.totalAmount } } }
Also, make sure you pass the root view to the parent class of Viewholder like this RecyclerView.ViewHolder(itemBinding.root)
by accessing the passed binding class object.
Attach the binding
to the ViewHolder instead of the View
class CardViewHolder(val binding: CardBinding) : RecyclerView.ViewHolder(binding.root)
You pass the binding, the binding passes binding.root
to RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardViewHolder { val binding = CardBinding.inflate(LayoutInflater.from(parent.context), parent, false) return CardViewHolder(binding) }
Then access anywhere with:
holder.binding.title
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With