Home > other >  Get binding in data ViewHolder
Get binding in data ViewHolder

Time:03-18

this is my current ViewHolder code, which I would like to modify to let me access the elements throught the binding variable:

class MenuViewHolder(
    parent: ViewGroup,
    private val onClick: (BaselineLink) -> Unit
) : RecyclerView.ViewHolder(
    LayoutInflater.from(parent.context)
        .inflate(R.layout.list_item_menu, parent, false)
) {

    private val textTitle: AppCompatTextView = itemView.findViewById(R.id.text_title)

The result I want in the last line is

private val textTitle: AppCompatTextView = binding.textTitle

I know I need to modify the line:

LayoutInflater.from(parent.context).inflate(R.layout.list_item_menu, parent, false)

But if I change it as

val inflater = LayoutInflater.from(parent.context)
val binding = PromotionItemBinding.inflate(inflater)

It doesn't work.

CodePudding user response:

You can't declare properties in the super-constructor call.

There are three ways to do this:

  1. Declare your binding property in the primary constructor so you can pass the root view of the binding to the superconstructor. You will have to inflate the binding outside the class:
class MenuViewHolder(
    val binding: ListItemMenuBinding,
    private val onClick: (BaselineLink) -> Unit
) : RecyclerView.ViewHolder(binding.root) {

    private val textTitle: AppCompatTextView = binding.textTitle
}

// In onCreateViewHolder:
return MenuViewHolder(ListItemMenuBinding.inflate(LayoutInflator.from(parent), parent, false) {
    // your click listener
}
  1. This is like 1, but to keep it self-contained you add a secondary constructor that does the inflation. So, you will also need a secondary constructor so you can use your parent parameter to determine the binding:
class MenuViewHolder private constructor(
    val binding: ListItemMenuBinding,
    private val onClick: (BaselineLink) -> Unit
) : RecyclerView.ViewHolder(binding.root) {

    constructor(
        parent: ViewGroup,
        onClick: (BaselineLink) -> Unit
    ): this(
            ListItemMenuBinding.inflate(LayoutInflater.from(parent.context), parent, false),
            onClick
        )

    private val textTitle: AppCompatTextView = binding.textTitle
}
  1. Keep your existing inflation method, and declare your binding as a property where you bind it to the existing instance that you have already inflated:
class MenuViewHolder(
    parent: ViewGroup,
    private val onClick: (BaselineLink) -> Unit
) : RecyclerView.ViewHolder(
    LayoutInflater.from(parent.context)
        .inflate(R.layout.list_item_menu, parent, false)
) {
   
    private val binding = ListItemMenuBinding.bind(itemView)
    private val textTitle: AppCompatTextView = binding.textTitle

}
  • Related