#概要
Androidの標準APIで提供されているRadioButton
とRadioGroup
。
複数のRadioButton
を1つのRadioGroup
の中に入れ子にすれば、その中で同時に一つだけが選択可能になる、とここまではいいのだが、RadioButton
は自由に配置することが許されない。
#なんでRadioButtonは自由に動かせない?
ドキュメントでもなんでも見ればわかるのだが、android.widget.RadioGroup
は**android.widget.LinearLayout
を継承している**ため。
LinearLayoutが何だかはみんな知ってるでしょう。
つまり横1列か縦1列にしか並べられないということ。
なんでやねん!!
#解決策
ということで、作っちゃいました。そういうクラス。
import android.util.Log;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class FreeRadioGroup {
private List<RadioButton> registeredRadioButtons = new ArrayList<>();
public FreeRadioGroup(){
}
public void addChild(RadioButton rb){
if(registeredRadioButtons.contains(rb)){
Log.w("FreeRadioGroup", "RadioButton already registered. Abort registering");
}else {
registeredRadioButtons.add(rb);
rb.setOnCheckedChangeListener(OCL);
}
}
public void removeChild(RadioButton rb){
if(!registeredRadioButtons.contains(rb)){
Log.w("FreeRadioGroup", "RadioButton is not registered. Abort unregistering");
}else {
registeredRadioButtons.remove(rb);
rb.setOnClickListener(null);
}
}
public int getSelectedButtonIndex(){
for(int i=0,n=registeredRadioButtons.size();i<n;i++){
if(registeredRadioButtons.get(i).isChecked()){
return i;
}
}
return -1;
}
@Nullable
public RadioButton getSelectedButton(){
for(int i=0,n=registeredRadioButtons.size();i<n;i++){
RadioButton r = registeredRadioButtons.get(i);
if(r.isChecked()){
return r;
}
}
return null;
}
private final CompoundButton.OnCheckedChangeListener OCL = new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(registeredRadioButtons.contains((RadioButton)compoundButton) && b){
for(RadioButton r : registeredRadioButtons){
if(r.equals((RadioButton)compoundButton)){
continue;
}
r.setChecked(false);
}
}
}
};
}
とりあえず丸コピして使っていただいて構いません。
addChild(RadioButton rb)
で登録したいRadioButton
を登録すると、登録したものの中で同時に1つだけが選択される仕組み。
逆になんでこれが公式に実装されてないのか疑問に思うレベルで必要だと思うのだが……。
#現状の問題点
・ボタンの状態が変わった時に呼ばれるリスナーを他に登録しようとすると上書きになってしまうため使えない
自分が使う分には今のところこれで困ってないので、時間があるときに考えておきます。あるいは何かいい方法があったらコメントで教えて頂ければと。OnClickの方は普通に使えるのでそれだけで済むのであれば問題ないはず。