Pablo A. Martínez Pablo A. Martínez - 28 days ago 5
Android Question

How to create instance of generic class passing a method reference in constructor with kotlin

Now that I'm using kotlin as my main programing language I'm trying to simplify Android's Recyclerview implementation logic and I'm stuck at following point:

Let's say I have defined the following ViewHolder class, where a click position event is propagated via a method reference in the constructor.

class CustomViewHolder(itemView: View, val onClick: (Int) -> Unit)) : RecyclerView.ViewHolder(itemView){
itemView.setOnClickListener {
onClick.invoke(adapterPosition)
}
}


How could I build an instance of a generic class that has a method reference in the constructor?

My recyclerview implementation has a generic class in the constructor and also an entity reference to be able to create an instance of my CustomViewHolder class by reflection at onCreateViewHolder:

class CustomAdapter<HolderClassGeneric>(val entityClass: Class<HolderClassGeneric>) : RecyclerView.Adapter<HolderClassGeneric>() {

/*
Usual recyclerview stuff
*/

//Method that I want to be called when a list item is clicked
fun onListItemClicked(position: Int) {
//do stuff
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HolderClassGeneric {
val view = LayoutInflater.from(parent.context).inflate(listItemLayoutResourceId, parent, false)

val constructor: Constructor<HolderClassGeneric>
val instance: HolderClassGeneric
//I'M STUCK HERE
constructor = entityClass.getConstructor(View::class.java, ?¿?¿?¿?¿)
instance = constructor.newInstance(view, this::onListItemClicked)

return instance

}


If what I want to achieve is not possible, would it be possible to pass the method reference using a setter by reflection?

Answer Source

A Kotlin lambda is usually translated as a FunctionX object, being X the number of parameters it has, so if you're looking for the representation of a lambda function like (Int) -> Unit it would be Function1<Int, Unit> so you could simply do:

entityClass.getConstructor(View::class.java, Function1::class.java)