Replacing Kotlin synthetic imports in RecyclerViewAdapter

Since synthetic imports will be deprecated in the long run, I began replacing them with viewbindings. This worked out good so far, I’m however facing difficulties when building a view inside a recyclerview adapter.

//other stuff [...]

private lateinit var binding: FinapiBankItemBinding

override fun onCreateViewHolder(
    parent: ViewGroup,
    viewType: Int
): FinApiBankItemViewHolder {
    binding = FinapiBankItemBinding.inflate(LayoutInflater.from(parent.context))
    return FinApiBankItemViewHolder(binding.root as ConstraintLayout)
}

//more stuff [...]

override fun onBindViewHolder(
    holder: FinApiBankItemViewHolder,
    position: Int
) {
    if (data != null && data.size > position) {
        val currentItem = data[position]
        buildView(holder.paymentAccountBaseView, currentItem)
    }
}

// endregion

// region methods

private fun buildView(view: View, item: FinApiBank) {

    //binding.bankNameTextView.text = item.name
    //binding.bicTextView.text = item.bic

    view.findViewById<TextView>(R.id.bankName_TextView).text = item.name
    view.findViewById<TextView>(R.id.bic_TextView).text = item.bic

    binding.root.setOnClickListener {
        parentViewModel.getAndNavWebform(item.externalId!!)
    }
}

In the buildView method, the two lines I commented out do not work as expected. The view gets built properly, but somehow there are refreshing issues and old data gets rendered in the end (even when stepping into it and seeing the correct values getting written in the fields).

When using the traditional findViewById or even viewBinding (which is not an option), everything works as expected.

The data used in this recyclerview gets exchanged quite often, since it displays search results that are updated on user input.

Answer

You can also search this RecyclerView with bindings However i edited your code a bit.

Try something like this:

override fun onCreateViewHolder(
    parent: ViewGroup,
    viewType: Int
): FinApiBankItemViewHolder {
    binding = FinapiBankItemBinding.inflate(LayoutInflater.from(parent.context),parent,false)
    return FinApiBankItemViewHolder(binding)
}

//more stuff [...]

override fun onBindViewHolder(
    holder: FinApiBankItemViewHolder,
    position: Int
) {
    if (data != null && data.size > position) {
        val currentItem = data[position]
        holder.buildView(holder.binding, currentItem)
    }
}

// endregion

// region methods
inner class FinApiBankItemViewHolder(val binding: FinapiBankItemBinding): RecyclerView.ViewHolder(binding.root) {

fun buildView(view: FinapiBankItemBinding, item: FinApiBank) {

    binding.bankNameTextView.text = item.name
    binding.bicTextView.text = item.bic

    binding.root.setOnClickListener {
        parentViewModel.getAndNavWebform(item.externalId!!)
    }
}
}