2017-06-02 55 views
3

我想我已经找到了一个使用kotlin for android的怪癖,或者在我对语法的理解上存在一些空白。Kotlin Android Button.onClickListener导致NoSuchMethodError

试图设置一个按钮的onClickListener抛出一个NoSuchMethodError

这里的过错

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) 
      } 
     }) 

和这里的堆栈跟踪输出

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) 

任何人都知道怎么了代码?

回答

6

有趣的是,我没有得到这个错误,你的代码编译为我。然而,它不会工作的原因不同:你在传递一个lambda作为{}中的侦听器,这意味着它的内容将在发生click事件时执行。虽然没有代码可以运行,但您只需定义一个名为onClicklocal function,这将永远不会被调用。

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

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

有两种方法可以解决你的语法:

首先,你可以使用object expression创建监听器,这是非常接近你写的东西,并且是沿着经典的Java的线解决方案,明确创建一个匿名类(注意,OnClickListener接口实际上是View类下):

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

或者你可以使用更短,更科特林的语法,当你TR的IDE会建议Ÿ使用以前的多头形态,无论如何,通过使SAM conversion使用:

button.setOnClickListener { 
    val intent = ... 
} 

该解决方案使用拉姆达就像你的初始代码没有,它只是不命名它转换为明确哪些接口,并丢弃()这不需要单个lambda参数。

1

尝试

button.setOnClickListener { 
    // Handler code here 
} 
相关问题