我正在尝试创建一个扩展函数来为Recycler视图适配器创建视图持有者对象
inline fun <reified T: RecyclerView.ViewHolder> ViewGroup.createViewHolder(@LayoutRes res: Int): T {
val inflater = LayoutInflater.from(context)
val itemView = inflater.inflate(res, this, false)
// return ViewHolder Object
}
如何创建扩展RecyclerView.ViewHolder的T类型的对象,以便我可以从函数返回。
答案 0 :(得分:6)
一个干净的替代解决方案是显式传递构造函数。它甚至不会更冗长,因为可以推断出类型参数,不需要再指定。使用方式如下:
val viewHolder = my_view_group.create(::MyViewHolder, R.layout.my_layout)
像这样实施:
inline fun <reified T: RecyclerView.ViewHolder> ViewGroup.create(createHolder: (View) -> T, @LayoutRes res: Int): T {
val inflater = LayoutInflater.from(context)
val itemView = inflater.inflate(res, this, false)
return createHolder(itemView)
}
答案 1 :(得分:2)
这个解决方案非常难看,但我认为“理论上”可以起作用:
inline fun <reified T: RecyclerView.ViewHolder> ViewGroup.create(@LayoutRes res: Int): T {
val inflater = LayoutInflater.from(context)
val itemView = inflater.inflate(res, this, false)
return T::class.java.getConstructor(View::class.java).newInstance(itemView)
}
最后一行的作用是:
1.获取匹配T
的{{1}}构造函数
2.在该构造函数上调用T(view: View)
,向其传递您膨胀的视图
改编自https://discuss.kotlinlang.org/t/generic-object-creation/1663/5
的解决方案只需通过以下方式致电:
newInstance
答案 2 :(得分:0)
不是所述问题的答案,但应该对到达这里想要摆脱 Thing(Foo::class.java, ...)
并使用 Thing<Foo>(...)
的人有所帮助。
您需要做的就是在 invoke
中添加具体化的 companion object
。
之前
class Thing<E : Enum<E>>(cls: Class<E>, value: String? = null) : Iterable<E> {
...
}
val thing = Thing(Foo::class.java, ...)
之后
class Thing<E : Enum<E>>(cls: Class<E>, value: String? = null) : Iterable<E> {
...
companion object {
// Lets us construct using Thing<Foo>(...) instead of Thing(Foo::class.java, ...)
inline operator fun <reified T : Enum<T>> invoke(value: String? = null) = Thing(T::class.java, value)
}
}
val thing = Thing<Foo>(...)