我似乎无法绕过Kotlin仿制药,请帮忙
我阅读了here和here,但仍然不确定如何进行这项工作。我有一个RecyclerView适配器,该适配器使用抽象的父BaseFieldVH作为ViewHolder类。
所以Adapter类看起来像这样:
class MyAdapter() : RecyclerView.Adapter<BaseFieldVH<*>>() {
...
override fun onBindViewHolder(holder: BaseFieldVH<*>, position: Int) {
holder.bind(data[position])
}
}
ViewHolder实现如下所示:
abstract class BaseFieldVH<in FF : BaseFormField>
(itemView: View) : RecyclerView.ViewHolder(itemView) {
...
abstract fun bind(formField: FF)
}
但是实际调用holder.bind(data[position])
时显示错误:
Out-projected type 'BaseFieldVH<*>' prohibits the use of 'public
abstract fun bind(formField: FF): Unit defined in ...
什么都不用?
我也尝试使用BaseFieldVH<in Nothing>
定义适配器,但是由于尝试将Nothing放到需要BaseFormField的函数中而出现类型不匹配错误。
使用BaseFormField
使用BaseFieldVH<iBaseFormField>
定义适配器实际上可以解决绑定问题,但是在onCreateViewHolder中,视图持有者的类型不匹配:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseFieldVH<BaseFormField> {
val itemView: View
when (viewType) {
HEADER_TYPE -> {
itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.item_header, parent, false)
return HeaderVH(itemView)
}
HeaderVH是BaseFieldVH的扩展,因此类型不匹配
答案 0 :(得分:2)
此问题的答案似乎是您无法实现为绑定指定泛型的ViewHolder类。我的猜测是因为编写了RecyclerView.Adapter Java和任何Kotlin扩展都太严格而无法正确实现。
如果您可以反驳这个结论,请告诉我!
我发现this帖子以我能理解的方式解释了整个投影概念。
最后,我放弃了控制ViewHolder的Type的尝试:
abstract class BaseFieldVH
(itemView: View) : RecyclerView.ViewHolder(itemView) {
...
abstract fun bind(formField: Any)
}
这意味着BaseFieldVH的每个子类都必须在其绑定函数中进行某种类型检查。例如:
class HeaderVH
(itemView: View) : BaseFieldVH(itemView) {
...
override fun bind(headerField: Any) {
if (headerField is HeaderField) {
// do something
}
}
}
但是现在至少我没有收到任何错误。
答案 1 :(得分:0)
如果数据列表中有多个复杂对象(为了在回收者视图中显示不同的项目),则还需要指定您的所有者。
这里的想法是您提供适配器,而不是由Holder来决定如何处理每种对象类型。
class MyAdapter() : RecyclerView.Adapter<BaseFieldVH<*>>() {
...
override fun onBindViewHolder(holder: BaseFieldVH<*>, position: Int) {
val item = data[position]
holder as BaseFieldVH<DATA_ITEM_TYPE>
item as DATA_ITEM_TYPE
holder.bind(item)
}
}