14.ArkUI Radio的介绍和使用
ArkUI Radio 组件介绍与使用指南
什么是 Radio 组件?
Radio(单选框)是 ArkUI 中的单选按钮组件,允许用户从一组互斥的选项中选择一个选项。它通常用于表单、设置界面等需要用户做出单一选择的场景。
Radio 的核心特性
- 单选功能:一组 Radio 中只能选择一个
- 状态管理:支持选中和未选中两种状态
- 标签支持:可以添加文字标签
- 自定义样式:可修改颜色、大小等外观属性
- 事件响应:支持选择状态变化的回调
基本使用方法
单个 Radio 使用
@Entry
@Component
struct SingleRadioExample {@State isChecked: boolean = falsebuild() {Column() {Radio({ value: 'option1', group: 'group1' }).checked(this.isChecked).onChange((isChecked: boolean) => {this.isChecked = isCheckedconsole.log('Radio状态变化:', isChecked)})Text(this.isChecked ? '已选中' : '未选中').margin({ top: 10 })}.width('100%').height('100%').justifyContent(FlexAlign.Center)}
}
Radio 组使用
@Entry
@Component
struct RadioGroupExample {@State selectedValue: string = 'option1'private options = [{ value: 'option1', label: '选项1' },{ value: 'option2', label: '选项2' },{ value: 'option3', label: '选项3' }]build() {Column() {Text('当前选择: ' + this.selectedValue).fontSize(20).margin({ bottom: 20 })ForEach(this.options, (item) => {Row() {Radio({ value: item.value, group: 'myGroup' }).checked(this.selectedValue === item.value).onChange((checked: boolean) => {if (checked) {this.selectedValue = item.value}})Text(item.label).margin({ left: 10 })}.margin({ bottom: 10 })})}.width('100%').height('100%').padding(20)}
}
高级用法
自定义样式
@Entry
@Component
struct StyledRadioExample {@State selectedColor: string = 'red'private colors = [{ value: 'red', label: '红色' },{ value: 'green', label: '绿色' },{ value: 'blue', label: '蓝色' }]build() {Column() {Text('选择你喜欢的颜色:').fontSize(18).margin({ bottom: 20 })ForEach(this.colors, (color) => {Row() {Radio({ value: color.value, group: 'colorGroup' }).checked(this.selectedColor === color.value).onChange((checked: boolean) => {if (checked) {this.selectedColor = color.value}}).radioStyle({pointColor: Color.White,activeColor: color.value,inactiveColor: '#dddddd',size: 20,strokeWidth: 2})Text(color.label).fontColor(color.value).margin({ left: 10 })}.margin({ bottom: 15 })})Divider().margin({ vertical: 20 })Text('当前选择: ' + this.selectedColor).fontSize(16).fontColor(this.selectedColor)}.width('100%').height('100%').padding(20)}
}
与 List 结合使用
@Entry
@Component
struct RadioListExample {@State selectedId: number = 1private items = [{ id: 1, name: 'iPhone 15', price: '¥7999' },{ id: 2, name: '华为 Mate 60', price: '¥6499' },{ id: 3, name: '小米 14', price: '¥3999' },{ id: 4, name: '三星 S23', price: '¥5699' }]build() {Column() {Text('请选择您想购买的商品:').fontSize(18).margin({ bottom: 15 })List({ space: 10 }) {ForEach(this.items, (item) => {ListItem() {Row() {Radio({ value: item.id.toString(), group: 'productGroup' }).checked(this.selectedId === item.id).onChange((checked: boolean) => {if (checked) {this.selectedId = item.id}}).margin({ right: 15 })Column() {Text(item.name).fontSize(16).fontWeight(FontWeight.Bold)Text(item.price).fontSize(14).fontColor('#ff5500')}.layoutWeight(1)}.width('100%').padding(15).borderRadius(8).backgroundColor(this.selectedId === item.id ? '#f0f9ff' : '#ffffff')}})}.width('100%').layoutWeight(1)Button('确认选择', { type: ButtonType.Capsule }).width('80%').height(40).margin({ top: 20 }).backgroundColor('#1890ff').enabled(this.selectedId !== 0).onClick(() => {const selectedItem = this.items.find(item => item.id === this.selectedId)AlertDialog.show({title: '确认选择',message: `您已选择: ${selectedItem?.name}
价格: ${selectedItem?.price}`,confirm: {value: '确定',action: () => {console.log('用户确认选择')}}})})}.width('100%').height('100%').padding(20)}
}
实际应用示例
设置页面单选
@Entry
@Component
struct SettingsPage {@State fontSize: string = 'medium'@State theme: string = 'light'@State notification: boolean = truebuild() {Navigation() {Scroll() {Column() {// 字体大小设置Text('字体大小').fontSize(18).margin({ top: 20, bottom: 10 })Row() {Radio({ value: 'small', group: 'fontGroup' }).checked(this.fontSize === 'small').onChange((checked) => checked && (this.fontSize = 'small')).radioStyle({ size: 16 })Text('小').fontSize(14).margin({ left: 5, right: 20 })Radio({ value: 'medium', group: 'fontGroup' }).checked(this.fontSize === 'medium').onChange((checked) => checked && (this.fontSize = 'medium')).radioStyle({ size: 18 })Text('中').fontSize(16).margin({ left: 5, right: 20 })Radio({ value: 'large', group: 'fontGroup' }).checked(this.fontSize === 'large').onChange((checked) => checked && (this.fontSize = 'large')).radioStyle({ size: 20 })Text('大').fontSize(18).margin({ left: 5 })}.margin({ bottom: 20 })Divider()// 主题设置Text('主题模式').fontSize(18).margin({ top: 20, bottom: 10 })Column() {Radio({ value: 'light', group: 'themeGroup' }).checked(this.theme === 'light').onChange((checked) => checked && (this.theme = 'light')).width('100%').height(40)Radio({ value: 'dark', group: 'themeGroup' }).checked(this.theme === 'dark').onChange((checked) => checked && (this.theme = 'dark')).width('100%').height(40)Radio({ value: 'auto', group: 'themeGroup' }).checked(this.theme === 'auto').onChange((checked) => checked && (this.theme = 'auto')).width('100%').height(40)}.margin({ bottom: 20 })Divider()// 通知设置Text('通知设置').fontSize(18).margin({ top: 20, bottom: 10 })Row() {Radio({ value: 'enable', group: 'notifyGroup' }).checked(this.notification).onChange((checked) => this.notification = checked)Text('启用通知').margin({ left: 10 })}Row() {Radio({ value: 'disable', group: 'notifyGroup' }).checked(!this.notification).onChange((checked) => this.notification = !checked)Text('禁用通知').margin({ left: 10 })}.margin({ top: 10 })}.padding(20)}}.title('设置')}
}
问卷调查
@Entry
@Component
struct SurveyPage {@State answers: { [key: string]: string } = {q1: '',q2: '',q3: ''}private questions = [{id: 'q1',text: '1. 您如何评价我们的产品质量?',options: [{ value: 'excellent', label: '非常好' },{ value: 'good', label: '好' },{ value: 'average', label: '一般' },{ value: 'poor', label: '差' }]},{id: 'q2',text: '2. 您对我们的客户服务满意吗?',options: [{ value: 'very_satisfied', label: '非常满意' },{ value: 'satisfied', label: '满意' },{ value: 'neutral', label: '一般' },{ value: 'dissatisfied', label: '不满意' }]},{id: 'q3',text: '3. 您会向朋友推荐我们的产品吗?',options: [{ value: 'definitely', label: '一定会' },{ value: 'probably', label: '可能会' },{ value: 'not_sure', label: '不确定' },{ value: 'no', label: '不会' }]}]build() {Navigation() {Scroll() {Column() {Text('客户满意度调查').fontSize(22).fontWeight(FontWeight.Bold).margin({ bottom: 30 })ForEach(this.questions, (question) => {Column() {Text(question.text).fontSize(18).margin({ bottom: 15 })Column() {ForEach(question.options, (option) => {Row() {Radio({ value: option.value, group: question.id }).checked(this.answers[question.id] === option.value).onChange((checked) => {if (checked) {this.answers[question.id] = option.value}})Text(option.label).margin({ left: 10 })}.margin({ bottom: 8 })})}.margin({ left: 20, bottom: 30 })Divider()}})Button('提交问卷', { type: ButtonType.Capsule }).width('80%').height(45).margin({ top: 30 }).backgroundColor('#1890ff').enabled(Object.values(this.answers).every(answer => answer !== '')).onClick(() => {console.log('提交的答案:', this.answers)AlertDialog.show({title: '提交成功',message: '感谢您参与我们的调查!',confirm: {value: '确定',action: () => {router.back()}}})})}.padding(20)}}.title('问卷调查')}
}
注意事项
- 分组使用:同一组的 Radio 组件会自动互斥,确保使用相同的 group 名称
- 默认值设置:建议为 Radio 组设置默认选中项,避免用户未选择的情况
- 无障碍支持:为 Radio 添加有意义的标签,方便屏幕阅读器识别
- 性能考虑:当 Radio 数量很多时,考虑使用虚拟