
2.3.4 RadioButton和RadioContainer
RadioButton是HarmonyOS中的单选按钮,继承自AbsButton类,AbsButton继承自Button类。AbsButton是一个抽象类,以它作为父类的组件通常用来做选择按钮,比如单选按钮、多选按钮、开关按钮等。RadioButton 组件的属性从 AbsButton类中继承,RadioButton组件区别于一般 Button组件的属性见表2-8。
表2-8 RadioButton组件区别于一般Button组件的属性

单选按钮通常是需要用户在几个选项中做选择时应用的。下面来实现一个最简单的RadioButton组件。

在上述代码中,实现了一个 RadioButton 组件,ohos:text 属性的属性值为“男”,并且在它的前面有一个底色默认为白色的圆圈。当用户点击RadioButton组件时,代表这个单选按钮已经被选中,它的ohos:marked属性值会变为true,并且前面圆圈的颜色会发生变化,页面的预览效果如图2-40所示。

图2-40 单个单选按钮
下面增加两个RadioButton组件,分别为“男”和“女”,用来做性别选择。

页面的预览效果如图2-41所示。
我们有惯性思维,既然是单选按钮,那么只能从男和女之间选择一个,并且在选择了一个按钮后,另一个按钮就会变成未被选中状态。但是由于每个单选按钮都有被选中状态和未被选中状态,并不能影响其他按钮的状态,所以在上面的代码作用下,我们可以同时选中“男”和“女”,页面的预览效果如图2-42所示。

图2-41 多个单选按钮

图2-42 多个单选按钮的被选中状态
要解决这个问题,需要对按钮进行分组,保证只有同一个组内的单选按钮才是互斥的,这就需要用到RadioContainer组件。
RadioContainer组件继承自DirectionalLayout,其属性来自DirectionalLayout。从名字上来看,它是单选按钮的容器。我们可以使用这个组件对单选按钮进行分组,代码如下。


在 RadioButton 组件外层包裹了一层 RadioContainer 组件来标识此RadioContainer组件内的RadioButton组件是同一组的,内部的RadioButton组件具有互斥性,当选中其中某一个RadioButton组件后,其他RadioButton组件的状态都会变为未被选中,页面的预览效果如图2-43所示。
还可以通过 ohos:text_color_on、ohos:text_color_off、ohos:check_element属性对 RadioButton 组件进行样式上的修改。其他代码不变,对 RadioButton组件增加上面三个属性。

图2-43 带组别控制的多个单选按钮


这里的 ohos:check_element 属性引用了一个自定义样式文件 checkbox_check_element.xml,该文件保存在graphic目录下,内容如下。

该文件是样式选择文件,根节点为<state-container>,子标签包含两个item,代表两种组件状态。每个item都通过ohos:state属性进行按钮状态的选择,通过 ohos:element 属性指定该状态下的组件的样式文件。两个 item 分别针对RadioButton组件前面的圆形标识符被选中和未被选中进行了不同的样式选择,每种状态的样式文件都通过“$graphic”来引用。单选按钮被选中时的样式文件checkbox_element_checked.xml的代码如下。


这个资源文件指定了单选按钮被选中时,前面标识符的样式为带背景颜色的圆角矩形。当按钮未被选中时,仅把背景颜色改成灰色,样式文件checkbox_element_unchecked.xml的代码如下。

页面的预览效果如图2-44所示。

图2-44 带样式的单选按钮
下面用 Java 代码对单选按钮进行操作,首先为 RadioContainer 组件添加ohos:id属性。


在MainAbilitySlice中编写以下代码。

在上述代码中,添加了RadioContainer.CheckedStateChangedListener()事件监听方法,当 RadioContainer 组件内的 RadioButton 组件状态发生变化时会回调这个方法。在onCheckedChanged(RadioContainer radioContainer,int i)方法中,可以通过入参i的值来对单选按钮进行索引,按照单选按钮的摆放顺序,索引值从0开始递增。在这个案例中,值为“男”的单选按钮的索引值为0,值为“女”的单选按钮的索引值为 1。在对应的 switch-case 语句分支中,可以对不同的按钮进行区分来完成不同的操作。