【Androidアプリ開発】ButtonでリスナクラスとonClick属性

Androidアプリ開発でButtonタップをした時の処理を記述する方法として
リスナクラスを作成してリスナ登録する方法と、onClick属性を使用する方法の2パターンがありますが、
ふと、一つのボタンに両方の方法を実装した場合どうなるのか気になっちゃいましたので確認してみましょ

結論としては、1つのボタンに両方の方法を登録してもどちらか片方しか動かない!
詳しくみていきましょー

はじめに

Buttonタップした時の処理を記述する2つの方法は、以下の記事を参照してください

【Androidアプリ開発】Buttonを使う

続きを見る

一つのボタンに両方の方法を実装してみる

まずは、ソースコードを見てみましょう

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // リスナ登録する
        val listner = ButtonClickListener()
        val btn = findViewById<Button>(R.id.button)
        btn.setOnClickListener(listner)
        val imgbtn = findViewById<ImageButton>(R.id.imageButton)
        imgbtn.setOnClickListener(listner)
    }
    
    // リスナクラス
    private inner class ButtonClickListener : View.OnClickListener {
        override fun onClick(view: View) {
            when (view.id) {
                R.id.button -> {
                    Toast.makeText(applicationContext, "[Listener] Button Click!!", Toast.LENGTH_SHORT).show()
                }
                R.id.imageButton -> {
                    Toast.makeText(applicationContext, "[Listener] imageButton Click!!", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    // onClick属性用メソッド
    fun onClickButton(view: View) {
        when (view.id) {
            R.id.button -> {
                Toast.makeText(applicationContext, "[onClickButton] Button Click!!", Toast.LENGTH_SHORT).show()
            }
            R.id.imageButton -> {
                Toast.makeText(applicationContext, "[onClickButton] imageButton Click!!", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

15~26行目がリスナクラスの作成部分で、7~11行目がリスナ登録部分ですね
29~38行目がonClick属性用のメソッドです。
デザイン画面で、[Attributes]->[onClick]にonClickButton()メソッドを登録しておきます。

この状態で、実行してボタンを押すとどうなるかですね、両方動くのか?どちらかしか動かないのか?
結果はこちら↓

リスナクラスの処理が実行されました!

結論

ってことで、結論ですが、どちらかしか動かないんですねぇ~

まぁ、onClick属性も内部的にリスナ登録しているらしいので、どっちかしか動かないんですよね
今回のソースは、onClick属性で内部的にリスナ登録している処理より後にリスナクラスのリスナ登録が実行されて
上書きされているんじゃないかなぁと勝手に想像してます。

どちらのやり方でボタンタップ時の処理を記述するかは、コードの見易さや好みでいいような気がしますが、
同じような処理を行う複数のボタンがある場合は、リスナクラスをsetOnClickListener()でリスナ登録する方法が良さそうです。
全く処理内容が異なる場合は、メソッドを複数作成してonClick属性を使用した方がメソッド名で処理内容を想定できて良さそうです。

まぁ、どっちでやらなきゃいけないって決まりはないはずなんで、コーディング規約や好み、コードの見易さで判断しましょう
って感じですかねぇ~

以上、おつかれさまでしたー

スポンサーリンク

  • この記事を書いた人

まさじぃ

ダメプログラマ歴17年です。 プログラミング関連の事や、 自分で使って良かったもの等の紹介をメインにやっています。

-プログラミング
-