2017-06-02 6 views
3

私はアンドロイド用にkotlinを使用するという奇妙なことを発見したと思います。ボタンのonClickListenerを設定しようとKotlin Android Button.onClickListener NoSuchMethodErrorを引き起こします

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

してみてください。しかし、別の理由で動作しません:{}の内部のリスナーとしてラムダを渡しています。つまり、クリックイベントが発生したときにその内容が実行されます。しかし、内部で実行するコードはありません。onClickという名前のlocal functionを定義するだけで、呼び出されることはありません。あなたの構文を修正するには、2つの方法があります

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が提案するより短く、よりKotlinに似た構文を使用することができます

button.setOnClickListener { 
    val intent = ... 
} 

このソリューションは、あなたの最初のコードがやったようにラムダを使用して、それはちょうどそれが明示的に変換し、どのようなインタフェース名、および()をドロップしません:SAM conversionを利用して、とにかく前の長い形式を使用して、Y単一のラムダパラメータを必要としない。

1

は、あなたのコードは私のためにコンパイルし、興味深いことに、私はそのエラーを取得しない

button.setOnClickListener { 
    // Handler code here 
} 
関連する問題