Reputation: 8734
Here's a simplified code of what I am doing:
I have this custom ViewHolder
:
open class AsyncViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
....
}
I inherit from above ViewHolder
and later on need to create a AsyncCellAdapter
of the inherited type. I am doing this using Generics:
abstract class AsyncCellAdapter<T: AsyncCellAdapter.AsyncViewHolder>() : RecyclerView.Adapter<T>(){
....
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): T {
val viewHolder = T(View(parent.context)) //<----------Here's the problem
....
return viewHolder
}
....
}
The problem arises at the T
in the line T(View(parent.context))
It gives me error:
Type parameter T cannot be called as function
How do I create an instance of the inherited type using Generics and return that?
Upvotes: 1
Views: 302
Reputation: 93609
Due to type erasure, you cannot do this without passing the concrete class to the constructor. Or, to avoid having to use reflection to find and call the constructor, it would be cleaner to give the constructor a function parameter for constructing the ViewHolder, so you can just pass the a constructor reference.
Example:
abstract class AsyncCellAdapter<T: AsyncCellAdapter.AsyncViewHolder>(
private val viewHolderConstructor: (View)->T
): RecyclerView.Adapter<T>(){
//...
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): T {
val viewHolder = viewHolderConstructor(View(parent.context))
//...
return viewHolder
}
//...
}
// Example subclass:
class MyAdapter: AsyncCellAdapter<MyAdapter.MyViewHolder>(::MyViewHolder) {
class MyViewHolder(itemView: View): AsyncCellAdapter.AsyncViewHolder(itemView)
}
Upvotes: 5