0
0

More than 3 years have passed since last update.

同一のRadioGroupに入っているRadioButtonを画面上の自由な位置に配置したい

Last updated at Posted at 2020-04-21

概要

Androidの標準APIで提供されているRadioButtonRadioGroup

複数のRadioButtonを1つのRadioGroupの中に入れ子にすれば、その中で同時に一つだけが選択可能になる、とここまではいいのだが、RadioButtonは自由に配置することが許されない。

なんでRadioButtonは自由に動かせない?

ドキュメントでもなんでも見ればわかるのだが、android.widget.RadioGroupandroid.widget.LinearLayoutを継承しているため。

LinearLayoutが何だかはみんな知ってるでしょう。
つまり横1列か縦1列にしか並べられないということ。

なんでやねん!!

解決策

ということで、作っちゃいました。そういうクラス。

FreeRadioGroup.java

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の方は普通に使えるのでそれだけで済むのであれば問題ないはず。

0
0
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
0
0