クリック処理
マス目をクリック(タッチ)すると×を表示するようにした。
ソースコードは次の通りだ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
package com.example.myapplication import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import android.view.View import android.widget.ImageButton import kotlinx.android.synthetic.main.ticktacktoo.* class MainActivity : AppCompatActivity(), View.OnClickListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.ticktacktoo) textView3.text = "こんにちは" var imagebutton = Array(3) { emptyArray<ImageButton>() } imagebutton[0]=arrayOf(imageButton1,imageButton2,imageButton3) imagebutton[1]=arrayOf(imageButton4,imageButton5,imageButton6) imagebutton[2]=arrayOf(imageButton7,imageButton8,imageButton9) for(idx1 in imagebutton.indices){ for(idx2 in imagebutton[idx1].indices){ imagebutton[idx1][idx2].setImageResource(R.drawable.ic_baseline_check_box_outline_blank_24) imagebutton[idx1][idx2].setOnClickListener(this) } } } override fun onClick(p0: View?) { var button = p0 as ImageButton button.setImageResource(R.drawable.ic_baseline_close_24) } } |
23行目でsetOnClickListener命令を使いクリックした際に関数を実行するよう設定している。引数の「this」は自分自身のクラスを意味し、実行する関数がクラス内に存在することになる。
23 |
imagebutton[idx1][idx2].setOnClickListener(this) |
実行される関数名、引数は決まっており、インタフェースView.OnClickListenerで定義されているので10行目で実装している。
10 |
class MainActivity : AppCompatActivity(), View.OnClickListener { |
インタフェースの実装はJavaのように「implements」の記述は不要だ。インタフェースを記述すると該当行がエラーになるのでマウスカーソルを合わせナビゲーションパネルを表示する。
「implement members」をクリックするとさらにパネルが開くので、「OK」ボタンを押下。必要な関数が自動展開される。
1 2 3 |
override fun onClick(p0: View?) { TODO("Not yet implemented") } |
展開された関数内にクリック時の処理を記述していくことになる。29行から32行目だ。
29 30 31 32 |
override fun onClick(p0: View?) { var button = p0 as ImageButton button.setImageResource(R.drawable.ic_baseline_close_24) } |
この関数はImageButton以外の部品でも利用できる汎用的なものだ。従って引数として渡ってくる部品も「View」という汎用的なモノになっている。そのためImageButton特有の設定を行う場合は型変換(キャスト)する必要がある。それが30行目だ。
キャストする命令が「as」である。返還後に別変数buttonに格納している。
最後の31行目で画像×を設定している。
印をつける(setTag)
マス目をクリックすると特定処理が実行できた。しかし問題がある。処理内ではどのボタンがクリックされたかわからないのだ。今後クリックされたボタンに応じて複雑な処理を記述していきたい、どのボタンがクリックされたかマス目のように3×3の情報で特定したいところだ。
解決方法としてsetTag命令を利用する。これは部品に印(タグ)を付けることができる。これで各ボタンに3×3の座標情報を設定する。
各ImageButtonを処理している箇所に次の2行を追加する。
20 21 22 23 24 25 26 27 28 |
for(idx1 in imagebutton.indices){ for(idx2 in imagebutton[idx1].indices){ imagebutton[idx1][idx2].setImageResource(R.drawable.ic_baseline_check_box_outline_blank_24) imagebutton[idx1][idx2].setOnClickListener(this) var array = arrayOf(idx1,idx2) imagebutton[idx1][idx2].setTag(array) } } |
24行目で行、列に対応するidx1,idx2を配列化している。それを25行目のsetTag命令で設定している。
クリック時の処理では次のようにハンドリングする。
31 32 33 34 35 |
override fun onClick(p0: View?) { var button = p0 as ImageButton var array = button.getTag() as Array<Int> Log.d("MainActivity","x="+array[0]+"y="+array[1]) } |
33行目のgetTag命令で設定したタグを取得し数値配列にキャストしている。それを34行目で表示している。
実行しマス目をクリックすると、該当する座標が表示されるようになった。
1 2 3 4 |
D/MainActivity: x=1y=1 D/MainActivity: x=0y=0 D/MainActivity: x=2y=2 D/MainActivity: x=1y=0 |
部品ハンドリングの動作確認ができた。次回から三目並べアプリのプログラム/データ構造を考えていく予定だ。