Kotlin 类型不匹配:推断类型是 View!但 TextView 是预期的

Posted

技术标签:

【中文标题】Kotlin 类型不匹配:推断类型是 View!但 TextView 是预期的【英文标题】:Kotlin Type mismatch: inferred type is View! but TextView was expected 【发布时间】:2018-04-23 10:50:35 【问题描述】:

美好的一天! 在android Studio 3.0 中使用Kotlin 1.1.51,定位Android API 26 创建RecyclerView 和下一个ViewHolder,但在构建项目时收到错误:

类型不匹配:推断类型是 View!但 TextView 是预期的

所以我无法直接找到TextViewViewHolder 变量,但在附近找到了 - 找到 View,然后使用 as TextView 进行转换,正如您在 holder.textView 的代码中看到的那样。看起来不太好,那么有没有解决方案如何防止这个错误或者它是一个错误? RecyclerView.Adapter的代码:

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH 
        val view = LayoutInflater.from(parent.context)
                .inflate(R.layout.custom_item_view, parent, false)
        return VH(view)
    

    override fun onBindViewHolder(holder: VH, position: Int) 
        val event: TimelineEvent = items[position]

        // does not work because of error in VH class
        holder.timeView.text = event.time

        // works
        (holder.textView as TextView).text = event.text
    

    class VH(itemView: View) : RecyclerView.ViewHolder(itemView) 
        // error: Type mismatch: inferred type is View! but TextView was expected
        val timeView: TextView = itemView.findViewById(R.id.timeline_item_time)

        // works fine
        val textView: View = itemView.findViewById(R.id.timeline_item_text)
    

【问题讨论】:

使用较新的(比 1.1.51)和最近的 1.2.71 最近的 Kotlin 版本,错误消失了 【参考方案1】:

您似乎尚未达到 API 级别 26 或更高级别。那时 findViewById 已更改,因此它返回通用 T 而不是基 View 类,这使您可以在 these ways 中从 Kotlin 使用它。

您可以按照other answer 中的@AlexTa 建议手动转换findViewById 调用的结果,或者您可以将您的支持库版本更新为26 或更高版本 - 目前最新的是27.0.0。这些新版本可从Google's Maven repository 获得。

【讨论】:

抱歉,我使用的是 API 26,将使用此信息更新我的问题 您的目标可能是 26,但如果您要扩展 AppCompatActivity,那么支持库版本必须至少是 26 的第一个稳定版本。 你知道supportlib版本不能低于compileSdkVersion和compileSdkVersion不能低于targetSdkVersion吗?【参考方案2】:

您只需要将找到的视图转换为预期类型即可:

val timeView: TextView = itemView.findViewById(R.id.timeline_item_time) as TextView

val timeView: TextView = itemView.findViewById<TextView>(R.id.timeline_item_time)

【讨论】:

感谢您的回答,但两种解决方案均无效。首先是因为 API 26 ir 会显示错误 Type inference failed: Not enough information to infer parameter T in fun &lt;T : View!&gt; findViewById(id: Int): T! Please specify it explicitly. 对于第二个 Studio 会建议删除显式类型参数,但在构建时会显示类型不匹配的相同错误。【参考方案3】:

这个问题已经有好几年了,但也许我的回答会帮助那些在像我一样犯了一个简单的错误后遇到这个问题的人。

我遇到了一个类似的错误(我的是inferred type is View but ImageView was expected),当我在这里阅读答案时,我意识到我有两个由 Android Studio 中的主要/详细模板生成的布局。我在res/layout/fragment_item_detail.xml 中将一个元素(id/item_detail)从TextView 更改为ImageView,但我只为常规布局而不是res/layout-sw600dp/fragment_item_detail.xml 中的布局这样做

由于相同的 id 在两种布局中具有不同的类型,因此绑定无法将关​​联的视图强制转换为 ImageView。相反,它退回到共同的父级,即View

将两个元素都更改为 ImageView(这正是我想要的)修复了错误。

因此,为避免此类错误,您需要做的一件事是确保同名布局文件中具有相同 id 的布局元素在所有布局文件夹中具有相同的类。

【讨论】:

以上是关于Kotlin 类型不匹配:推断类型是 View!但 TextView 是预期的的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin - 类型不匹配:推断类型是 Any?但布尔值是预期的

kotlin gradle dsl问题:类型不匹配:推断类型是字符串但URI!预计

Android Kotlin - viewBinding 类型不匹配:推断类型为 DrawerLayout 但应为 ConstraintLayout

类型不匹配:推断的类型是 String 但在 kotlin 中需要 Charset

类型不匹配:推断类型为 Unit 但预期为 Boolean

Kotlin:功能类型不匹配