2017-06-02 53 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 
} 
相關問題