【发布时间】:2018-06-26 18:04:58
【问题描述】:
我似乎无法理解 Kotlin 泛型,请帮助
我阅读了here 和here,但我仍然无法确定如何完成这项工作。我有一个 RecyclerView 适配器,它使用抽象的父 BaseFieldVH 作为 ViewHolder 类。
所以适配器类看起来像这样:
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 的扩展,所以存在类型不匹配
【问题讨论】:
-
我也处理过 Kotlin 泛型复杂性,感觉肮脏/hacky 的方式是用 java 编写逻辑,然后将其转换为 Kotlin :grimacing: 。否则,这只是挖掘 Kotlin 文档的问题
-
感谢@ElliotM 的建议。我试过你的技术——它没有用,现在我觉得很脏;)。 kotlin 转换产生以下结果:
class MyAdapter(): RecyclerView.Adapter<*>()和 Android Studio 警告我projections are not allowed for immediate arguments of a supertype。所以我正在查看here,我会尽快回复您。