Android Studio开发实战:从零基础到App上线 (移动开发丛书)
上QQ阅读APP看书,第一时间看更新

3.2 特殊按钮

本节介绍几个常用的特殊控制按钮,包括复选框CheckBox的监听器用法、开关按钮Switch的属性定义、仿iOS开关按钮的实现、单选按钮RadioButton及其组布局RadioGroup的监听器用法,以及如何更换这些控件的按钮图标。

3.2.1 复选框CheckBox

在学习复选框之前,先了解一下CompoundButton。在Android体系中,CompoundButton类是抽象的复合按钮,因为是抽象类,所以不能直接使用。实际开发中用的是CompoundButton类的几个派生类,主要有复选框CheckBox、单选按钮RadioButton以及开关按钮Switch,这些派生类都可使用CompoundButton的属性和方法。

CompoundButton在布局文件中主要使用下面两个属性。

● checked:指定按钮的勾选状态,true表示勾选,false表示未勾选。默认未勾选。

● button:指定左侧勾选图标的图形。如果不指定就使用系统的默认图标。

CompoundButton在代码中可使用下列4种方法进行设置。

● setChecked:设置按钮的勾选状态。

● setButtonDrawable:设置左侧勾选图标的图形。

● setOnCheckedChangeListener:设置勾选状态变化的监听器。

● isChecked:判断按钮是否勾选。

复选框CheckBox是CompoundButton一个最简单的实现,点击复选框勾选,再次点击取消勾选。CheckBox通过setOnCheckedChangeListener方法设置勾选监听器,对应的监听器要实现接口CompoundButton.OnCheckedChangeListener。下面是复选框自定义勾选监听器的代码:

            private class CheckListener implements CompoundButton.OnCheckedChangeListener{
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    String desc = String.format("您勾选了控件%d,状态为%b", buttonView.getId(),
    isChecked);
                    Toast.makeText(MainActivity.this, desc, Toast.LENGTH_LONG).show();
                }
            }

要更换复选框左侧的勾选图像,可将button属性修改为自定义的勾选图形。下面是一个勾选图形状态定义的例子,如果是勾选状态,就显示图形check_choose;如果取消勾选,就显示图形check_unchoose。

        <selector xmlns:android="http://schemas.android.com/apk/res/android">
            <item android:state_checked="true" android:drawable="@drawable/check_choose"/>
            <item android:drawable="@drawable/check_unchoose"/>
        </selector>

3.2.2 开关按钮Switch

Switch是开关按钮,Android从4.1.2版本开始支持该控件。其实Switch是一个高级版本的CheckBox,在选中与取消选中时可展现的界面元素比CheckBox丰富。Switch新添加的属性和设置方法见表3-2。

表3-2 Switch控件的属性和设置方法说明

Switch是升级版的CheckBox,实际开发中用得不多。原因之一是大家觉得Switch的默认界面很丑,如图3-5和图3-6所示,方方正正的图标有点土又有点呆板;原因之二是iPhone作为高大上手机的代表,大家都觉得iOS的UI很漂亮,于是无论是用户还是客户,都希望App做得与iOS控件相像,iOS的开关按钮UISwitch就成了大家仿照的对象。

图3-5 Switch控件的“关”状态

图3-6 Switch控件的“开”状态

现在我们要让Android实现类似iOS的开关按钮,主要思路是借助状态列表图形StateListDrawable,首先定义一个状态列表,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属性设置为该状态图形,当然button属性要先设置为@null。为什么这里修改background属性,而不直接修改button属性呢?因为button属性是有限制的,无论多大的图片,都只显示一个小小的图标,可是小小的图标怎么能体现用户高大上的身份呢?所以这里必须使用background,要它有多大就能有多大,这才够炫、够档次。

最后看看这个仿iOS开关按钮的效果,如图3-7和图3-8所示。这下开关按钮脱胎换骨,又圆又鲜艳,看起来好看很多。

图3-7 仿iOS按钮的“关”状态

图3-8 仿iOS按钮的“开”状态

3.2.3 单选按钮RadioButton

单选按钮要在一组按钮中选择其中一项,并且不能多选,这要求有个容器确定这组按钮的范围,这个容器便是RadioGroup。RadioGroup实质上是个布局,同一组RadioButton都要放在同一个RadioGroup节点下。RadioGroup有orientation属性可指定下级控件的排列方向,该属性为horizontal时,单选按钮在水平方向排列;该属性为vertical时,单选按钮在垂直方向排列。RadioGroup下面除了RadioButton,还可以挂载其他子控件(如TextView、ImageView等)。这样看来,RadioGroup就是一个特殊的线性布局,只不过多了管理单选按钮的功能。

下面是RadioGroup常用的3个方法。

● check:选中指定资源编号的单选按钮。

● getCheckedRadioButtonId:获取选中状态单选按钮的资源编号。

● setOnCheckedChangeListener:设置单选按钮勾选变化的监听器。

RadioButton默认未选中,点击后显示选中,但是再次点击不会取消选中。只有点击同组的其他单选按钮时,原来选中的单选按钮才会取消选中。另外,单选按钮的选中事件一般不由RadioButton处理,而是由RadioGroup响应。选中事件在实现时,首先要写一个选中监听器实现接口RadioGroup.OnCheckedChangeListener,然后调用RadioGroup对象的setOnCheckedChangeListener方法注册该监听器。

下面是用RadioGroup实现选中监听器的代码:

            class RadioListener implements RadioGroup.OnCheckedChangeListener{
                @Override
                public void onCheckedChanged(RadioGroup group, int checkedId) {
                    Toast.makeText(MainActivity.this, "您选中了控件"+checkedId,
    Toast.LENGTH_LONG).show();
                }
            }

RadioButton经常会更换按钮图标,如果通过button属性变更图标,那么图标与文字就会挨得很近,如图3-9所示的第一个单选按钮。为了拉开图标与文字之间的距离,得换成drawableLeft属性展示新图标(不要忘了把button改为@null),此时再设置drawablePadding即可指定间隔距离。修改后的单选按钮效果如图3-10所示,可以看到图标与文字之间的距离明显增大了。

图3-9 图标设置在button属性上

图3-10 图标设置在drawableLeft属性上

前面给不同的按钮自定义按钮图标先后用了3个属性,即自定义CheckBox图标时的button属性、仿iOS开关按钮时的background属性以及自定义RadioButton时的drawableLeft属性。下面总结一下这3个图标设置方式分别适用的场合。

● button:主要用于图标大小要求不高,间隔要求也不高的场合。

● background:主要用于能够以较大空间显示图标的场合。

● drawableLeft:主要用于对图标与文字之间的间隔有要求的场合。