ArkUI Radio 组件介绍与使用指南
什么是 Radio 组件?
Radio(单选框)是 ArkUI 中的单选按钮组件,允许用户从一组互斥的选项中选择一个选项。它通常用于表单、设置界面等需要用户做出单一选择的场景。
Radio 的核心特性
- 单选功能:一组 Radio 中只能选择一个
- 状态管理:支持选中和未选中两种状态
- 标签支持:可以添加文字标签
- 自定义样式:可修改颜色、大小等外观属性
- 事件响应:支持选择状态变化的回调
基本使用方法
单个 Radio 使用
typescript
@Entry
@Component
struct SingleRadioExample {
@State isChecked: boolean = false
build() {
Column() {
Radio({ value: 'option1', group: 'group1' })
.checked(this.isChecked)
.onChange((isChecked: boolean) => {
this.isChecked = isChecked
console.log('Radio状态变化:', isChecked)
})
Text(this.isChecked ? '已选中' : '未选中')
.margin({ top: 10 })
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
Radio 组使用
typescript
@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)
}
}
高级用法
自定义样式
typescript
@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 结合使用
typescript
@Entry
@Component
struct RadioListExample {
@State selectedId: number = 1
private 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)
}
}
实际应用示例
设置页面单选
typescript
@Entry
@Component
struct SettingsPage {
@State fontSize: string = 'medium'
@State theme: string = 'light'
@State notification: boolean = true
build() {
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('设置')
}
}
问卷调查
typescript
@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 数量很多时,考虑使用虚拟