1

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?

2 Answers 2

3

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)
Sign up to request clarification or add additional context in comments.

Comments

0

You can use a parameter function like a factory.

class CustomAdapter<HolderClassGeneric>(val entityFactory: (View,  (Int) -> Unit) -> 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 instance = entityFactory(view, this::onListItemClicked)

        return instance

}

1 Comment

sorry, this is not what I'm looking for

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.