![Hello HarmonyOS!:鸿蒙应用开发从入门到精通](https://wfqqreader-1252317822.image.myqcloud.com/cover/437/43738437/b_43738437.jpg)
2.3.4 RadioButton和RadioContainer
RadioButton是HarmonyOS中的单选按钮,继承自AbsButton类,AbsButton继承自Button类。AbsButton是一个抽象类,以它作为父类的组件通常用来做选择按钮,比如单选按钮、多选按钮、开关按钮等。RadioButton 组件的属性从 AbsButton类中继承,RadioButton组件区别于一般 Button组件的属性见表2-8。
表2-8 RadioButton组件区别于一般Button组件的属性
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_132_2.jpg?sign=1738832393-UPJzCi3qfvILMCBftninFlk9atmLv9lk-0-d688a4f374e3da31f9e312cbe8578c6d)
单选按钮通常是需要用户在几个选项中做选择时应用的。下面来实现一个最简单的RadioButton组件。
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_133_1.jpg?sign=1738832393-QO3A1L1dbokQQhHMMcgNFjpHOSJmNN39-0-4dd88668d9d0317fb6fc73bb010070de)
在上述代码中,实现了一个 RadioButton 组件,ohos:text 属性的属性值为“男”,并且在它的前面有一个底色默认为白色的圆圈。当用户点击RadioButton组件时,代表这个单选按钮已经被选中,它的ohos:marked属性值会变为true,并且前面圆圈的颜色会发生变化,页面的预览效果如图2-40所示。
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_133_2.jpg?sign=1738832393-HX0WV57VbYG2oxCRR4xD34sLEKG6vyQf-0-f21a61657a7519136343bd319c0a587f)
图2-40 单个单选按钮
下面增加两个RadioButton组件,分别为“男”和“女”,用来做性别选择。
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_134_1.jpg?sign=1738832393-2XVFMoWuGfbjcygsvNI9ZgSMBN7c6bcr-0-e468c68ac6f8ae3dc0b7f54d06e03472)
页面的预览效果如图2-41所示。
我们有惯性思维,既然是单选按钮,那么只能从男和女之间选择一个,并且在选择了一个按钮后,另一个按钮就会变成未被选中状态。但是由于每个单选按钮都有被选中状态和未被选中状态,并不能影响其他按钮的状态,所以在上面的代码作用下,我们可以同时选中“男”和“女”,页面的预览效果如图2-42所示。
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_135_1.jpg?sign=1738832393-GzDqPsRhRgDyhMOaCgx5ACGFOFw85SGm-0-3463c5b5e3f07e97b8607eb507014904)
图2-41 多个单选按钮
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_135_2.jpg?sign=1738832393-YHA0vZlQqkXKDWiIfWX2VdisZNg7n3ju-0-f996fc6e69c29d03c7d1f18473cd2cf2)
图2-42 多个单选按钮的被选中状态
要解决这个问题,需要对按钮进行分组,保证只有同一个组内的单选按钮才是互斥的,这就需要用到RadioContainer组件。
RadioContainer组件继承自DirectionalLayout,其属性来自DirectionalLayout。从名字上来看,它是单选按钮的容器。我们可以使用这个组件对单选按钮进行分组,代码如下。
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_135_3.jpg?sign=1738832393-VOoBwXmxPkvdHenyXHDiU3ItslYRfxnC-0-7bfcc7c975a78073c740acec5dd7caa2)
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_136_1.jpg?sign=1738832393-2Kr4XHw68M8uUJX6QIvqoDGYI16WgRof-0-799f28cdfd0e9da11635869dc29b6777)
在 RadioButton 组件外层包裹了一层 RadioContainer 组件来标识此RadioContainer组件内的RadioButton组件是同一组的,内部的RadioButton组件具有互斥性,当选中其中某一个RadioButton组件后,其他RadioButton组件的状态都会变为未被选中,页面的预览效果如图2-43所示。
还可以通过 ohos:text_color_on、ohos:text_color_off、ohos:check_element属性对 RadioButton 组件进行样式上的修改。其他代码不变,对 RadioButton组件增加上面三个属性。
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_136_2.jpg?sign=1738832393-UMECLhvf4xLp1pUntZqS462G4pJ4LjBS-0-4a9a7c3ad5ad00cdc3916ee85409b663)
图2-43 带组别控制的多个单选按钮
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_136_3.jpg?sign=1738832393-ZOUbWXZvMsavg0eFZ2gQTAAM9QIwfjXv-0-4945a7d26a71a040edb176d6e3155304)
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_137_1.jpg?sign=1738832393-E5u8W8S0oQrwhDNW2TwUvmMU6AiPxJyo-0-73d994784328e472249e0407855c0602)
这里的 ohos:check_element 属性引用了一个自定义样式文件 checkbox_check_element.xml,该文件保存在graphic目录下,内容如下。
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_137_2.jpg?sign=1738832393-jPL48t0ZAMnoN5fzQxt8zTzQbnuEBNAq-0-7ec379a6c6bd14548466afb73f51a213)
该文件是样式选择文件,根节点为<state-container>,子标签包含两个item,代表两种组件状态。每个item都通过ohos:state属性进行按钮状态的选择,通过 ohos:element 属性指定该状态下的组件的样式文件。两个 item 分别针对RadioButton组件前面的圆形标识符被选中和未被选中进行了不同的样式选择,每种状态的样式文件都通过“$graphic”来引用。单选按钮被选中时的样式文件checkbox_element_checked.xml的代码如下。
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_137_3.jpg?sign=1738832393-yW0TfXiPaFOSQL32e5FaKmO8J4h4bP52-0-43cae10b97a00ec0bad206f87ce351b6)
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_138_1.jpg?sign=1738832393-lkykGeg2zLefPOT1jhF6jjs5Aqj5pCga-0-dc70a51742f0bb950b60981618874acb)
这个资源文件指定了单选按钮被选中时,前面标识符的样式为带背景颜色的圆角矩形。当按钮未被选中时,仅把背景颜色改成灰色,样式文件checkbox_element_unchecked.xml的代码如下。
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_138_2.jpg?sign=1738832393-YqHILmnx6GE2RYHlCdWamkYdsmyReswJ-0-e589bb7262a6afc691fd856f2df0a338)
页面的预览效果如图2-44所示。
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_138_3.jpg?sign=1738832393-f2sQIu52MzQCwS4UrGXYSfniyYd8RCq5-0-4a1bf207b4c4d26c48557067a5eea9d7)
图2-44 带样式的单选按钮
下面用 Java 代码对单选按钮进行操作,首先为 RadioContainer 组件添加ohos:id属性。
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_138_4.jpg?sign=1738832393-Zvuphr5lZm05320Crde93qkigeIi6Ela-0-ceeeb6e2d3c31e3e109c560e8e6a46f3)
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_139_1.jpg?sign=1738832393-VQlZTwz1ncdFeyLKIk1OOP93fHzcfJ1m-0-618fa1d8ab5dfc1ceb27a0897b9c52b0)
在MainAbilitySlice中编写以下代码。
![](https://epubservercos.yuewen.com/0FFABF/23020655009774306/epubprivate/OEBPS/Images/42868_139_2.jpg?sign=1738832393-yQP0i1rY4p3hs1nq0FYBuW52izHHBnPw-0-98774716609867faa65b13f139ca6e69)
在上述代码中,添加了RadioContainer.CheckedStateChangedListener()事件监听方法,当 RadioContainer 组件内的 RadioButton 组件状态发生变化时会回调这个方法。在onCheckedChanged(RadioContainer radioContainer,int i)方法中,可以通过入参i的值来对单选按钮进行索引,按照单选按钮的摆放顺序,索引值从0开始递增。在这个案例中,值为“男”的单选按钮的索引值为0,值为“女”的单选按钮的索引值为 1。在对应的 switch-case 语句分支中,可以对不同的按钮进行区分来完成不同的操作。