LoginSignup
9
3

More than 1 year has passed since last update.

【Kotlin】何気なく書いているsetOnClickListenerについて

Posted at

Androidアプリを開発したくて、kotlinで勉強しています。
何気なく書いていたコードに、kotlinならでは?のコード変形があったので
自分と同じように、あまり気に留めていなかった人向けに。
あと自分でもまた見返せるように。。。

まずは最終形態から

ボタンのクリックイベントにリスナー登録するときによく書く

    val btn = findViewById<Button>(R.id.btn)
    btn.setOnClickListener{
        Log.d("click","click!!")
    }

みたいなやつ。最終的にはこの書き方が多い。実はこの形態に行き着くまでに色々あるらしい。

形態1

private inner class MyClickListener : OnClickListener{
    override fun onClick(view: View?) {
        Log.d("click","click!!")
    }
}

~~~省略~~~

    val btn = findViewById<Button>(R.id.btn)
    btn.setOnClickListener(MyClickListener())

めちゃくちゃ丁寧に?書いたやつ。ここからスタート。

まず、setOnClickListener は引数に
OnClickListener を継承したクラスのインスタンスをとる。
だから、OnClickListener を継承した MyClickListener を定義してあげて
setOnClickListener には、そのインスタンスを渡す。

ちなみに、OnClickListener で実装しないといけないメソッドは
onClick メソッドの一つだけ。 ←これが後で重要。

形態2

    val btn = findViewById<Button>(R.id.btn)
    btn.setOnClickListener(object : OnClickListener {
        override fun onClick(view: View?) {
            Log.d("click", "click!!")
        }
    })

イベントリスナーみたいなその場でしか使わないようなものに
いちいち MyClickListener なんて名前を付けてクラス定義するのは面倒くさい。
そこで「オブジェクト式」というのを使うらしい。
定義しつつそのインスタンスを渡す!って感じ。
これでカタマリ感も出てスッキリ!ただ、最終形態まではまだまだ遠い。

形態3

    val btn = findViewById<Button>(R.id.btn)
    btn.setOnClickListener({ view: View? ->
        Log.d("click", "click!!")
    })

オブジェクト式は便利な上に、今回のようなインターフェースが一つのメソッドしか持たない場合はさらに素敵な書き換えができる。
オブジェクト式 → ラムダ式 となる。

引数にメソッドを渡している感が出ていて
この状態が個人的には分かりやすくて結構好きだが、Kotlinはまだまだ行くらしい。

形態4

    val btn = findViewById<Button>(R.id.btn)
    btn.setOnClickListener({
        Log.d("click", "click!!")
    })

ラムダ式の引数が一つなら
ラムダ式の中の「 引数 -> 」を省略できるらしい。さらにスッキリ!
ちなみに、この省略した引数はラムダ式の中で「it」で参照できるようです。

形態5

    val btn = findViewById<Button>(R.id.btn)
    btn.setOnClickListener(){
        Log.d("click", "click!!")
    }

ん?どこが変わった?って感じですが、ラムダ式が()の外に出ています。
関数の引数の最後がラムダ式の場合、そのラムダ式は()の外に出せるらしいです。
これの何が嬉しいのかなと思ったけど
パラメータ2つぐらい渡して、コールバック関数も渡して・・・みたいな関数があったときにスッキリするのかな?

    // 出さないパターン
    sampleFunc(para1,para2,{
        // 処理
    })

    // 出したパターン
    sampleFunc(para1,para2){
        // 処理
    }

・・・正直あんまり違いが分からない。
これにどういう嬉しポイントがあるのかどなたか教えていただければ助かります・・・!

形態6(最終形態)

    val btn = findViewById<Button>(R.id.btn)
    btn.setOnClickListener{
        Log.d("click", "click!!")
    }

最後は、関数の後の()が消えています。
関数の引数がラムダ式1つの場合は、()を省略できるらしいです。
(べ、別にそこまでしなくても良いんじゃ・・・)

最後に

こういう流れがあって、Kotlinでは素敵な書き方ができているようです。
setOnClickListenerの最終形態の書き方は
本とか見てても当たり前のように書かれているから、気にしていなかったけど
よく考えたら関数の後に{}を書いて、その中に処理書いてるのって変よね。

引数の最後がラムダ式の場合は・・・!とか
引数が1つの場合は・・・!とか
色々な条件が重なってのこの形だったんですね。

つまり逆に言うと
引数が1つでない場合とか、継承するクラスのメソッド複数ある場合とか
そういう時は、途中までしか形態変化できないことになりますね!

Kotlin、最近の言語って感じがして楽しい!!

9
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
3