目录
本文介绍了几个常用的特殊控制按钮,包括:如何使用复选框CheckBox及其勾选监听器、如何使用开关按钮Switch、如何借助状态列表图形实现仿IOS的开关按钮、如何使用单选按钮RadioButton和单选组RadioGroup及其选中监听器。
复选框CheckBox
在学习复选框之前,先了解一下CompoundButton类,在Android体系中,CompoundButton类是抽象的符合按钮,因为是抽象类,所以它不能直接使用。在实际开发中用的是CompoundButton的几个派生类,主要有复选框CheckBox、单选按钮RadioButton以及开关按钮Switch,这些派生类均可使用CompoundButton的属性和方法,加之CompoundButton本身继承了Button类,故以上几种按钮同时具备Button的属性和方法,它们之间的继承关系如图所示。
CompoundButton在XML文件中主要使用下面两个属性。
- checked:指定按钮的勾选状态,true表示勾选,false表示未勾选。默认为未勾选。
- button: 指定左侧勾选图标的图形资源,如果不指定就使用系统的默认图标。
CompoundButton在Java代码中主要使用下列4个属性。
- setChecked:设置按钮的勾选状态。
- setButtonDrawable:设置左侧勾选图标的图形资源。
- setOnCheckedChangeListener:设置勾选状态变化的监听器。
- isChecked:判断按钮是否勾选。
复选框CheckBox是CompoundButton一个最简单的实现控件,点击复选框将他勾选,再次点击取消勾选。复选框对象调用setOnCheckedChangeListener方法设置勾选监听器,这样在勾选和取消勾选时就会触发监听器的勾选事件。
首先编写活动页面的XML文件:
<CheckBox
android:id="@+id/ck_system"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="false"
android:button="@drawable/check_selector"
android:text="这是系统的CheckBox"
android:textSize="22sp"/>
接着编写对应的Java代码,主要是如何处理勾选监听器
// 从布局文件中获取名叫ck_system的复选框
CheckBox ck_system = findViewById(R.id.ck_system);
//给ck_system设置勾选监听器,一旦用户点击复选框,就触发监听器的onCheckedChanged方法
ck_system.setOnCheckedChangeListener(this);
@Override
public void onCheckedChanged(android.widget.CompoundButton buttonView, boolean isChecked){
if (buttonView.getId()==R.id.ck_system) {
String desc = String.format("您%s了这个CheckBox", isChecked ? "勾选" : "取消勾选");
buttonView.setText(desc);
}
}
开关按钮Switch
Switch是开关按钮,它像一个高级版本的CheckBox,在选中与取消选中时可展现的界面元素比复选框丰富。Switch控件新添加的XML属性说明如下:
- textOn:设置右侧开启时的文本。
- textOff:设置左侧关闭时的文本。
- track:设置开关轨道的背景。
- thumb:设置开关标识的图标。
虽然开关按钮是升级版的复选框,但它在实际开发中用的不多。因为Switch默认界面不够大气,而iPhone的界面很漂亮,于是iOs的开关按钮UISwitch就成了安卓开发者仿照的对象。
现在要让Android实现类似iOS的开关按钮,主要思路是借助状态列表图形,首先创建一个图形专用的XML文件,给状态列表指定选中与未选择时的开关图标:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"
android:drawable="@drawable/switch_on"/>
<item android:drawable="@drawable/switch_off"/>
</selector>
然后把CheckBox标签的background属性设置为@drawable/switch_selector,同时将botton属性设置为@null。
<CheckBox
android:id="@+id/ck_status"
android:layout_width="44dp"
android:layout_height="22dp"
android:gravity="bottom"
android:layout_marginTop="10dp"
android:layout_marginStart="200dp"
android:background="@drawable/switch_selector"
android:button="@null" />
为什么这里修改background属性,而不直接修改button属性。因为波疼痛属性有局限,无论多大的图片都只显示一个小小的图标,使用background属性,它有多大就能有多大。
单选按钮RadioButton
所谓单选按钮,指的是在一组按钮中选择其中一项,并且不能多选,这要求有个容器确定这组按钮的范围,这个容器便是单选组RadioGroup。单选组实质上是个布局,同一组RadioButton都要放在同一个RadioGroup节点下。RadioGroup提供了orientation属性指定下级控件的排列方向,该属性为horizontal时,单选按钮在水平方向排列;该属性为vertical时,单选按钮在垂直方向排列。RadioGroup下面处理RadioButton,还可以挂载其他子控件。单选组相当于特殊的线性布局,它们主要有以下两个区别:
- 单选组多了管理单选按钮的功能,而线性布局不具备该功能。
- 如果不指定orientation属性,那么单选组默认垂直排列,而线性布局默认水平排列。
下面是RadioGroup在Java代码中的3个常用方法。
- check:选中指定资源编号的单选按钮。
- getCheckedRadioButtonID:获取已选中单选按钮的资源编号。
- setOnCheckedChangeListener:设置单选按钮勾选变化的监听器。
与CheckBox不同的是,RadioButton默认未选中,点击后显示选中,但是再次点击不会取消选中。只有点击同组的其他单选按钮时,原来选中的单选按钮才会取消选中。单选按钮的选中事件不是由RadioButton处理,而是由RadioGroup处理。
XML文件:
<RadioGroup
android:id="@+id/rg_sex"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rb_male"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="男"/>
<RadioButton
android:id="@+id/rb_female"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="女"/>
</RadioGroup>
<TextView
android:id="@+id/tv_sex"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:textSize="22sp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"/>
Java代码:
RadioGroup rg_sex = findViewById(R.id.rg_sex);
rg_sex.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (checkedId == R.id.rb_male) {
tv_sex.setText("哇哦,你是个帅气的男孩");
} else if (checkedId == R.id.rb_female) {
tv_sex.setText("哇哦,你是个漂亮的女孩");
}
}
});
tv_sex = findViewById(R.id.tv_sex);