突出类型禁止使用方法 [英] Out-projected type prohibits the use of method

查看:273
本文介绍了突出类型禁止使用方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎无法绕过Kotlin仿制药,请帮忙

I can't seem to wrap my head around Kotlin generics, please help

我在此处阅读此处,但我仍然无法确定如何进行这项工作.我有一个RecyclerView适配器,该适配器使用抽象的父BaseFieldVH作为ViewHolder类.

I read here and here and I still can't determine how to make this work. I have a RecyclerView adapter that uses an abstracted parent BaseFieldVH as the ViewHolder class.

所以Adapter类看起来像这样:

So the Adapter class looks like this:

class MyAdapter() : RecyclerView.Adapter<BaseFieldVH<*>>() {
... 
    override fun onBindViewHolder(holder: BaseFieldVH<*>, position: Int) {
        holder.bind(data[position])
    }
}

ViewHolder实现如下所示:

And the ViewHolder implementation looks like this:

abstract class BaseFieldVH<in FF : BaseFormField>
    (itemView: View) : RecyclerView.ViewHolder(itemView) {
    ...
    abstract fun bind(formField: FF)
}

但是对holder.bind(data[position])的实际调用显示错误:

But the actual call to holder.bind(data[position]) is displaying the error:

Out-projected type 'BaseFieldVH<*>' prohibits the use of 'public 
abstract fun bind(formField: FF): Unit defined in ...

什么都不用?

我也尝试使用BaseFieldVH<in Nothing>定义适配器,但随后由于尝试将Nothing放到需要BaseFormField的函数中而收到Type Mismatch错误.

I've also tried defining the Adapter with BaseFieldVH<in Nothing> but then I get a Type Mismatch error for attempting to put Nothing into a function that requires a BaseFormField.

使用BaseFormField

使用BaseFieldVH<iBaseFormField>定义适配器实际上可以解决绑定问题,但是在onCreateViewHolder中,视图持有者的类型不匹配:

Defining the Adapter with BaseFieldVH<iBaseFormField> actually resolves the binding issue, but then in the onCreateViewHolder there is a type mismatch for the view holders:

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的扩展,因此类型不匹配

HeaderVH is an extension of BaseFieldVH, and so there's a type mismatch

推荐答案

此问题的答案似乎是您无法实现为绑定指定泛型的ViewHolder类.猜测是由于RecyclerView.Adapter是用Java编写的,并且任何Kotlin扩展都过于严格而无法正确实现这一事实.

It looks like the answer to this issue is that you can't implement a ViewHolder class that specifies a generic for binding. My guess is this arises from the fact that the RecyclerView.Adapter is written in Java and any Kotlin extension is too restrictive to implement it properly.

如果您可以反驳这个结论,请告诉我!

If you can contradict this conclusion, let me know!

我发现了这篇帖子,该帖子以一种我可以解释的方式解释了整个投影概念明白.

I found this post which explains the whole projection concept in a way that I could understand.

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

In the end I abandoned my attempt to control the Type for the ViewHolder:

abstract class BaseFieldVH
  (itemView: View) : RecyclerView.ViewHolder(itemView) {
  ...
  abstract fun bind(formField: Any)
}

这意味着BaseFieldVH的每个子类都必须在其绑定函数中进行某种类型检查.例如:

This means each child class of BaseFieldVH has to do some a type check in its bind function. For instance:

class HeaderVH
  (itemView: View) : BaseFieldVH(itemView) {
...
  override fun bind(headerField: Any) {
    if (headerField is HeaderField) {
      // do something
    }
}

}

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

But now at least I'm not getting any errors.

这篇关于突出类型禁止使用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆