Kotlin Android Button.onClickListener raises NoSuchMethodError

I think I found a quirk of using kotlin for android, or there is some gap in my understanding of the syntax.

Trying to set onClickListener

for a button is to do thisNoSuchMethodError

Here's the error code

button.setOnClickListener(Button.OnClickListener {
            fun onClick(view: View){
                val intent : Intent = Intent(this,DetailActivity::class.java)
                if(obj is String) {
                    intent.putExtra("Topic", obj)
                }
                startActivity(intent)
            }
        })

      

And here is the stop trace taken out

 java.lang.NoSuchMethodError: No static method OnClickListener(Lkotlin/jvm/functions/Function1;)Landroid/view/View$OnClickListener; in class Landroid/widget/Button; or its super classes (declaration of 'android.widget.Button' appears in /system/framework/framework.jar:classes2.dex)

      

Does anyone know what?

+3


source to share


2 answers


Interestingly, I am not getting this error, your code compiles for me. However, this won't work for another reason: you are passing the lambda as a listener internally {}

, which means that its content will be executed when the click event occurs. There is no code inside this code, but you just define a named local function that will never be called.onClick

button.setOnClickListener(Button.OnClickListener {
    fun onClick(view: View){
        ...
    }

    Log.d("TAG", "hi") // this is the code that would be executed on click events
})

      

There are two ways to correct your syntax:

First, you can use an expression object

to create a listener, this is pretty close to what you wrote and goes the lines of a classic Java solution, it explicitly creates an anonymous class (note that the interface is OnClickListener

actually in the class View

):



button.setOnClickListener(object: View.OnClickListener {
    override fun onClick(v: View?) {
        val intent = ...
    }
})

      

Or, you can use the shorter, more Kotlin-like syntax that the IDE will suggest when you try to use the previous long form anyway using SAM Transform :

button.setOnClickListener {
    val intent = ...
}

      

This solution uses a lambda in the same way as your original code, but it just doesn't specify which interface it will explicitly convert, and discards ()

which doesn't require a single lambda parameter.

+6


source


try it



button.setOnClickListener {
    // Handler code here
}

      

+1


source







All Articles