Android 外投影类型禁止使用方法

Android 外投影类型禁止使用方法,android,generics,kotlin,Android,Generics,Kotlin,我似乎无法理解Kotlin的仿制药,请帮忙 我读了很多书,但我仍然无法决定如何让它发挥作用。我有一个RecyclerView适配器,它使用抽象的父BaseFieldVH作为ViewHolder类 因此,适配器类如下所示: class MyAdapter() : RecyclerView.Adapter<BaseFieldVH<*>>() { ... override fun onBindViewHolder(holder: BaseFieldVH<*>

我似乎无法理解Kotlin的仿制药,请帮忙

我读了很多书,但我仍然无法决定如何让它发挥作用。我有一个RecyclerView适配器,它使用抽象的父BaseFieldVH作为ViewHolder类

因此,适配器类如下所示:

class MyAdapter() : RecyclerView.Adapter<BaseFieldVH<*>>() {
... 
    override fun onBindViewHolder(holder: BaseFieldVH<*>, position: Int) {
        holder.bind(data[position])
    }
}
abstract class BaseFieldVH<in FF : BaseFormField>
    (itemView: View) : RecyclerView.ViewHolder(itemView) {
    ...
    abstract fun bind(formField: FF)
}
什么都不用?

我还尝试使用
BaseFieldVH
定义适配器,但由于试图不向需要BaseFormField的函数中放入任何内容,因此出现了类型不匹配错误

使用BaseFormField

使用
BaseFieldVH
定义适配器实际上解决了绑定问题,但在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)
        }
override fun onCreateViewHolder(父级:ViewGroup,viewType:Int):BaseFieldVH{
val项目视图:视图
何时(视图类型){
标题类型->{
itemView=LayoutInflater.from(parent.context)
.充气(右布局图项目标题,父项,假)
返回标题ERVH(项目视图)
}

HeaderVH是BaseFieldVH的一个扩展,因此存在类型不匹配的问题。这个问题的答案似乎是,无法实现指定绑定泛型的ViewHolder类。我猜这是因为RecyclerView.Adapter是用Java编写的,任何Kotlin扩展都太有限我必须正确地实施它

如果你能反驳这个结论,让我知道

我找到了一篇以我能理解的方式解释整个投影概念的帖子

最后,我放弃了控制ViewHolder类型的尝试:

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
    }
}
}


但现在至少我没有收到任何错误。

如果数据列表中有多个复杂对象(以便在“回收器”视图中显示不同的项目),则还需要指定持有者

这里的想法是提供适配器,而不是持有者来决定如何处理每个对象类型

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)
    }
}
class MyAdapter():RecyclerView.Adapter(){
... 
覆盖BindViewHolder(支架:BaseFieldVH,位置:Int){
val项目=数据[位置]
作为BaseFieldVH的持有者
项目作为数据\u项目\u类型
持有人绑定(项目)
}
}

我也处理过Kotlin泛型的复杂性,感觉肮脏的方法是用java编写逻辑,然后将其转换为Kotlin:grimacing:。否则,就需要通过Kotlin docsThanks挖掘@ElliotM的建议。我尝试了你的技术-它不起作用,现在我感觉肮脏;)。Kotlin转换产生了以下结果:由于:
类MyAdapter():RecyclerView.Adapter()
和Android Studio警告我,超类型的直接参数不允许使用投影。
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)
    }
}