え・・・Androidってラジオボタンも名前と値をペアで持っていないの?
AndroidでHTMLの...のように名前と値を対比してSpinnerを表示するで、HTMLのSELECTタグが名前と値を持てるのにAndroidのコンボボックス(spinner)が名前と値をペアで持てないという話を書きましたが、ラジボタンも同じです。
名前と値をペアで持てません。HTMLができているのに、なんでAndroidで標準でそんな機能がないんでしょう?
と、いうことでHTMLのラジオボタンと同じようなことを実現するにはどうするか?考えてみました。
ラジオボタンの値を取得する
取り敢えず、ラジオボタンの名称でやってみる?
とりあえず、こんな画面を考えてみます。ボタンを押した時にラジオボタンのどっちが選択されているかを取得して、
ラジオ1だったら → 1
ラジオ2だったら → 2
をDBに更新するとか、HTTPでサーバに送るとか・・・そんなケースです。
ラジオボタンのレイアウトのテキストが取得できますので、そのテキストで条件分岐を書くと、
binding.button.setOnClickListener {
val id = binding.radioGroup.checkedRadioButtonId
val radioTxt = findViewById<RadioButton>(id).text.toString()
when (radioTxt) {
"ラジオ1" -> binding.radioValue.text = "ラジオ1が選択されました"
"ラジオ2" -> binding.radioValue.text = "ラジオ2が選択されました"
else -> {}
}
}
これは良くないです。レイアウトのデザインがモロ、コーディング中にかかれてしまっています。ボタンの名称が変わったら、コーディングも変えないといけません。
Tagを使ってみる。
AndroidのViewにsetTag()、getTag()というメソッドがあります。viewにタグというオブジェクトを関連付けることができます。これで、ラジオボタンのそれぞれに値を関連付けて、それを取ってくるようにします。今、
ラジオ1 → "1"
ラジオ2 → "2"
を関連付けるとします。単純なStringであれば、コードで書かなくてもLayout xmlの中で定義できます。引数はObjectなのでString以外の独自のクラス、Enumとかを関連付けしたい場合はコードで書く必要があります。
<RadioGroup
(中略)
<RadioButton
android:id="@+id/radioButton"
(中略)
android:tag="1"
android:text="ラジオ1" />
<RadioButton
android:id="@+id/radioButton2"
(中略)
android:tag="2"
android:text="ラジオ2" />
</RadioGroup>
コードはこのようになります。
binding.button.setOnClickListener {
val id = binding.radioGroup.checkedRadioButtonId
val radioVal = findViewById<RadioButton>(id).getTag() as String
binding.radioValue.text = "ラジオ${radioVal}が選択されました"
}
上のラジオボタンのテキストで条件分岐しているのと比べるとスッキリしていますし、ライアウトのデザインの変更がコードに影響しません。Tagについては公式のAndroid develpersを参照してください。
https://developer.android.com/reference/android/view/View#setTag(java.lang.Object)
https://developer.android.com/reference/android/view/View#getTag()
この例ではボタンのOnClickListenerを使ってボタンを押した契機でラジオボタンの値を取得していますが、ラジオボタンの選択を変更した時にすぐに値を取得することもできます。
RadioGroup#setOnCheckedChangeListenerを使います。この場合も同じ様にTagを使って、このようになります。
binding.radioGroup2.setOnCheckedChangeListener { radioGroup, i ->
val id = radioGroup.checkedRadioButtonId
val radioVal = findViewById<RadioButton>(id).getTag() as String
binding.radioOnCheckValue.text = "ラジオ${radioVal}が選択されました"
}
最後に
完成版はgitHubに置きました