Daniele
Daniele

Reputation: 4343

Kotlin - TypeCastException on view.getTag()

I have got a class called ItemClickSupport that attaches an ItemClick to a RecyclerView:

This is the init function:

init {
        mRecyclerView.setTag(R.id.item_click_support, this)
        mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener)
    }

and have a companion object to add it to the recyclerView:

companion object {

        fun addTo(view: RecyclerView): ItemClickSupport {
            var support: ItemClickSupport? = view.getTag(R.id.item_click_support) as ItemClickSupport
            if (support == null) {
                support = ItemClickSupport(view)
            }
            return support
        }
}

When I run my app and try to add the clickListener to the recyclerView, I get a

Caused by: kotlin.TypeCastException: null cannot be cast to non-null type com.dancam.subscriptions.Support.ItemClickSupport at com.dancam.subscriptions.Support.ItemClickSupport$Companion.addTo(ItemClickSupport.kt:80) at com.dancam.subscriptions.AddSubscription.AddSubscription.onCreate(AddSubscription.kt:79)

with the first error pointing to this line in the addTo function:

var support: ItemClickSupport? = view.getTag(R.id.item_click_support) as ItemClickSupport

and the second one to this in my main_activity:

ItemClickSupport.addTo(recyclerView!!).setOnItemClickListener(
                object: ItemClickSupport.OnItemClickListener {
                    override fun onItemClicked(recyclerView: RecyclerView, position: Int, v: View ) {
                        ...
                    }
                })

What am I missing?

Upvotes: 0

Views: 1454

Answers (1)

Ekeko
Ekeko

Reputation: 1979

From the Kotlin reference (https://kotlinlang.org/docs/reference/typecasts.html):

"Unsafe" cast operator

Usually, the cast operator throws an exception if the cast is not possible. Thus, we call it unsafe. The unsafe cast in Kotlin is done by the infix operator as (see operator precedence):

val x: String = y as String

Note that null cannot be cast to String as this type is not nullable, i.e. if y is null, the code above throws an exception. In order to match Java cast semantics we have to have nullable type at cast right hand side, like:

val x: String? = y as String?

You can also use the so called "Safe" (nullable) cast operator which, as far as I know, is equivalent:

val x: String? = y as? String

So in your specific case:

var support: ItemClickSupport? = view.getTag(R.id.item_click_support) as ItemClickSupport?

or

var support: ItemClickSupport? = view.getTag(R.id.item_click_support) as? ItemClickSupport

Upvotes: 1

Related Questions