RecyclerView适配器的Kotlin泛型

RecyclerView适配器的Kotlin泛型

问题描述:

我正在尝试编写通用的recyclerview适配器.我找到了一些例子.但是,仍无法弄清楚如何实现通用适配器.我写的代码是

I am trying to write a generic recyclerview adapter. I found a few examples. However, still could not figure out how to achieve a generic adapter. The code I have written is,

open abstract class BaseAdapter<T : RecyclerView.ViewHolder>(private val onClickListener: View.OnClickListener, @LayoutRes private val layoutResource:Int) :
        RecyclerView.Adapter<T>() {
        var items: MutableList<Item> = mutableListOf()

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): T  {
            val layout = LayoutInflater.from(parent.context).inflate(layoutResource, parent, false)
            layout.setOnClickListener(onClickListener)
            return T(layout)
        }

        override fun getItemCount(): Int {
            return items.size
        }
    }

我在第return T(layout)行出现错误.错误是Expression 'T' of type 'Int' cannot be invoked as a function. The function 'invoke()' is not found.

I am getting an error at line return T(layout). The error is Expression 'T' of type 'Int' cannot be invoked as a function. The function 'invoke()' is not found.

Kotlin不允许创建在类型参数中标识的类型的对象(不同于C#可以).

Kotlin doesn't allow creating object of type that was identified in type parameters (unlike C# can).

因此,在您的情况下,您可以保留没有onCreateViewHolder方法实现的抽象类.或者,您可以添加另一个抽象方法,然后在onCreateViewHolder中调用它.

So in your case you can leave abstract class without onCreateViewHolder method realization. Or you can add another abstract method and call it in onCreateViewHolder.

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): T  {
    val layout = LayoutInflater.from(parent.context).inflate(layoutResource, parent, false)
    layout.setOnClickListener(onClickListener)
    return createHolderInstance(layout)
}

abstract fun createHolderInstance(layout: View): T

这样,子类中的代码应该更少了.例如:

In this way there should be less code in child classes. For example:

class UsersAdapter(...) : BaseAdapter<UserHolder>(...) {
    override fun createHolderInstance(layout: View) = UserHolder(layout)
}