Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin Type mismatch: inferred type is View! but TextView was expected

Good day! Using Kotlin 1.1.51 in Android Studio 3.0, targeting Android API 26 to create RecyclerView with next ViewHolder, but receiving error on building the project:

Type mismatch: inferred type is View! but TextView was expected

So I can't find TextView directly to ViewHolder variable, but found around way - find View and after that cast with as TextView as you can see in the code for holder.textView. Doesn't look so good, so are there solutions how to prevent this error or is it a bug? The code of 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)
    }
like image 983
Eduards Pozarickis Avatar asked Nov 10 '17 08:11

Eduards Pozarickis


3 Answers

You just need to cast found view as expected type, to do so:

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

or

val timeView: TextView = itemView.findViewById<TextView>(R.id.timeline_item_time)
like image 55
AlexTa Avatar answered Oct 17 '22 17:10

AlexTa


It seems like you're not on API level 26 or newer yet. That's when findViewById was changed so that it returns a generic T instead of the base View class, which enables you to use it from Kotlin in these ways.

You can either manually cast the result of the findViewById call as @AlexTa suggested in the other answer, or you can update your support library version to 26 or later - the latest currently is 27.0.0. These new versions are available from Google's Maven repository.

like image 38
zsmb13 Avatar answered Oct 17 '22 18:10

zsmb13


This question is several years old, but maybe my answer will help someone who comes across this question after making a simple error like I just did.

I came across a similar error (mine was inferred type is View but ImageView was expected) and while I was reading the answers here, I realized that I had two layouts generated by the primary/detail template in Android Studio. I had changed an element (id/item_detail) from TextView to ImageView in res/layout/fragment_item_detail.xml, but I only did it for the regular layout, and not for the layout in res/layout-sw600dp/fragment_item_detail.xml

Since the same id had different types in the two layouts, the binding couldn't cast the associated view to ImageView. Instead, it fell back to the common parent, which is View.

Changing both elements to ImageView (which is what I wanted anyway) fixed the error.

So, one thing you need to do to avoid this sort of error is to make sure that layout elements with the same id in the same-named layout files have the same class across all layout folders.

like image 1
Brian Cooley Avatar answered Oct 17 '22 16:10

Brian Cooley