7.4 单选按钮

从一组选项中选择一个,不能多选,同一组中的选项是互斥的,这种控件叫做“单选按钮”,由于非常像老式收音机的按钮,只要按下一个其他的按钮就会弹起,因此也称为“收音机按钮”。

7.4.1 RadioButton

在Android中,“单选按钮”是RadioButton, RadioButton的默认样式如图7-16所示。为了将多个RadioButton放置在一组中,使其具有互斥性,需要将这些RadioButton放置在一个RadioGroup中。

图7-16 单选按钮默认样式

RadioButton对应类是android.widget.RadioButton,类图如图7-17所示,从图中可见android.widget.RadioButton继承了android.widget.Button,这说明RadioButton是一种按钮。RadioButton有一个特有属性android:checked,该属性用了设置RadioButton的选中状态,它是一个布尔值,true表示选中,false表示未选中。

图7-17 RadioButton类图

7.4.2 RadioGroup

android.widget.RadioGroup是一个视图组(ViewGrop),它是RadioButton的容器,只有放到同一RadioGroup中的RadioButton才能产生互斥的效果,android.widget. RadioGroup类图如图7-18所示,从类图中可见android.widget.RadioGroup属于线性布局。

图7-18 RadioGroup类图

7.4.3 实例:使用单选按钮

图7-19是使用单选按钮的实例,在屏幕上出现了两组RadioButton,在同一组内的RadioButton(男和女之间,英语和德语之间)是互斥性,不同组之间没有关系。

图7-19 单选按钮实例

布局文件activity_main.xml代码如下:

      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical">
          …
          <RadioGroup                                                               ①
              android:id="@+id/RadioGroup01"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content">
              <RadioButton                                                          ②
                  android:id="@+id/RadioButton01"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:checked="true"                                            ③
                  android:text="@string/male"
                  android:textSize="@dimen/size"/>
              <RadioButton                                                          ④
                  android:id="@+id/RadioButton02"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="@string/female"
                  android:textSize="@dimen/size"/>
        </RadioGroup>
        …
        <RadioGroup                                                                 ⑤
            android:id="@+id/RadioGroup02" 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
            <RadioButton                                                            ⑥
                android:id="@+id/RadioButton01"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="true"                                              ⑦
                android:text="@string/lang_1" 
                android:textSize="@dimen/size"/>  
            <RadioButton                                                            ⑧
                android:id="@+id/RadioButton02"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/lang_2"
                android:textSize="@dimen/size"/>
        </RadioGroup>
      </LinearLayout>

在布局文件中声明了两个RadioGroup,见代码第①行和第⑤行。RadioGroup是线性布局,每一个RadioGroup中有两个RadioButton。

第一个RadioGroup中的代码第②行声明“男”RadioButton,代码第③行android:checked="true"是设置选中,代码第④行声明“女”RadioButton。

第二个RadioGroup中的代码第⑥行声明“英语”RadioButton,代码第⑦行android:checked="true"是设置选中,代码第⑧行声明“德语”RadioButton。

MainActivity.java代码如下:

        public class MainActivity extends AppCompatActivity
                implements RadioGroup.OnCheckedChangeListener{                             ①

            RadioGroup mRadioGroup1;
            RadioGroup mRadioGroup2;
            TextView mTextView;

            @Override
            protected void onCreate(Bundle savedInstanceState){
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                mTextView=(TextView) findViewById(R.id.TextView01);
                //注册RadioGroup01 监听器
                mRadioGroup1 =(RadioGroup) findViewById(R.id.RadioGroup01);
                mRadioGroup1.setOnCheckedChangeListener(this);                             ②
                //注册RadioGroup02监听器
                mRadioGroup2 =(RadioGroup) findViewById(R.id.RadioGroup02);
                mRadioGroup2.setOnCheckedChangeListener(this);                             ③
            }

            @Override
            public void onCheckedChanged(RadioGroup rdp, int checkedId){                   ④
                switch(rdp.getId()){                                                       ⑤
                    case R.id.RadioGroup01:
                        RadioButton rb1 =(RadioButton)findViewById(checkedId);             ⑥
                        mTextView.setText(rb1.getText());                                  ⑦
                        break;
                    case R.id.RadioGroup02:
                        RadioButton rb2 =(RadioButton)findViewById(checkedId);
                        mTextView.setText(rb2.getText());
                }
            }
        }

上述代码第①行是声明MainActivity实现RadioGroup.OnCheckedChangeListener接口,这样MainActivity就成为了RadioGroup事件监听器,该接口要求实现代码第④行的onCheckedChanged方法。代码第②行注册当前MainActivity作为RadioGroup01监听器,代码第③行注册MainActivity作为RadioGroup02监听器。

由于RadioGroup01和RadioGroup02监听器都是MainActivity,因此在代码第④行的事件处理方法onCheckedChanged(RadioGroup rdp, int checkedId)中,需要区分事件源是RadioGroup01还是RadioGroup02,其中方法rdp参数就是事件源,checkedId参数是选中的RadioButton id。代码第⑤行rdp.getId()是获得RadioGroup的id,通过id进行比较是否等于R.id.RadioGroup01或R.id.RadioGroup02,则可以判断事件源是哪个RadioGroup。由于id是整数,所以可以使用switch语句。

代码第⑥行findViewById方法查找id为checkedId的RadioButton对象。