ArkUI Radio:单选有边界,用户才不迷路
ArkUI Radio:单选有边界,用户才不迷路
这篇我们单独看 Radio。
Radio 最适合互斥选择:一组选项里只能选一个。新手很容易把它和 Checkbox 混着用,结果页面看起来能多选,实际业务又只认一个值,用户就会迷糊。
所以这个 Demo 不写表单提交,也不讲状态刷新。我们先把 Radio 自己的边界看清楚:同组单选、默认选中、样式颜色和禁用态。
参考文档:
- https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkui
- https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-ui-development
同组单选才是 Radio 的重点
Radio 创建时要给 value 和 group。
Radio({ value: 'daily', group: 'notifyFrequency' })
.checked(true)
group 表示它属于哪一组。语义上,同一组里的选项互斥,只能选一个。
这里我们先用静态页面展示默认状态,不写 onChange。这不是偷懒,而是为了把组件本身讲清楚。状态变化后面会放到状态管理章节。
默认选中要有理由
默认项不是随便选一个。比如“轻量、标准、完整”三种模式里,案例默认选“标准模式”,因为它更像大多数用户的起点。
Radio({ value: 'standard', group: 'mode' })
.checked(true)
如果默认项选得太激进,用户还没看懂页面,就已经被你带到一个特殊配置里了。
radioStyle 负责颜色细节
radioStyle 可以改选中背景、未选中边框和中间指示点颜色。
Radio({ value: 'daily', group: 'notifyFrequency' })
.radioStyle({
checkedBackgroundColor: '#2563EB',
uncheckedBorderColor: '#CBD5E1',
indicatorColor: '#FFFFFF'
})
选中颜色可以跟当前模块主色走,未选中边框则建议轻一点。边框太重,页面会到处都是圆点,反而不好扫。
禁用态别只变灰
禁用态很简单:
Radio({ value: 'company', group: 'policy' })
.checked(true)
.enabled(false)
但只变灰不够。案例里把原因写在旁边:由管理员统一配置、试用结束后开放。用户知道为什么不能点,就不会怀疑页面出错。
打开案例页时,可以看三件事:同组是否互斥,默认项是否合理,禁用项是否说清原因。你现在项目里有没有那种“看着能多选,其实只能选一个”的设置?这种地方通常就该换成 Radio。
完整示例代码
文件位置:entry/src/main/ets/pages/arkUI/basic/ArkUIRadioDemo.ets
@Entry
@Component
struct ArkUIRadioDemo {
@Builder
sectionTitle(title: string, desc: string) {
Column({ space: 4 }) {
Text(title)
.width('100%')
.fontSize(16)
.fontWeight(700)
.fontColor('#0F172A')
Text(desc)
.width('100%')
.fontSize(13)
.fontColor('#64748B')
.lineHeight(20)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
}
@Builder
optionText(title: string, desc: string, enabled: boolean) {
Column({ space: 4 }) {
Text(title)
.width('100%')
.fontSize(15)
.fontWeight(700)
.fontColor(enabled ? '#0F172A' : '#94A3B8')
Text(desc)
.width('100%')
.fontSize(12)
.fontColor(enabled ? '#64748B' : '#94A3B8')
.lineHeight(18)
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
}
@Builder
radioRow(title: string, desc: string, group: string, value: string, checked: boolean, enabled: boolean,
checkedColor: string, uncheckedColor: string, indicatorColor: string, borderColor: string) {
Row({ space: 12 }) {
Radio({ value: value, group: group })
.checked(checked)
.radioStyle({
checkedBackgroundColor: checkedColor,
uncheckedBorderColor: uncheckedColor,
indicatorColor: indicatorColor
})
.enabled(enabled)
this.optionText(title, desc, enabled)
}
.width('100%')
.height(66)
.padding({ left: 14, right: 14, top: 12, bottom: 12 })
.backgroundColor(enabled ? '#FFFFFF' : '#F1F5F9')
.border({ width: 1, color: enabled ? borderColor : '#CBD5E1' })
.borderRadius(8)
}
build() {
Scroll() {
Column({ space: 18 }) {
Text('ArkUI Radio')
.width('100%')
.fontSize(24)
.fontWeight(700)
.fontColor('#0F172A')
Text('单选有边界,用户才不迷路')
.width('100%')
.fontSize(22)
.fontWeight(700)
.fontColor('#111827')
Text('这一页只看 Radio 自己:同组单选、默认选中、样式颜色和禁用态。复杂表单和状态刷新,先不放进来。')
.width('100%')
.fontSize(14)
.fontColor('#64748B')
.lineHeight(22)
Column({ space: 12 }) {
this.sectionTitle('同一组只能选一个', 'Radio 适合互斥选择。比如提醒频率,只能每天、每周、每月选一个。')
this.radioRow('每天提醒', '适合高频任务,用户会更常收到提示。', 'notifyFrequency', 'daily', true, true,
'#2563EB', '#CBD5E1', '#FFFFFF', '#BFDBFE')
this.radioRow('每周提醒', '适合不紧急但要定期回看的内容。', 'notifyFrequency', 'weekly', false, true,
'#2563EB', '#CBD5E1', '#FFFFFF', '#BFDBFE')
this.radioRow('每月提醒', '适合低频复盘,不要打扰太多。', 'notifyFrequency', 'monthly', false, true,
'#2563EB', '#CBD5E1', '#FFFFFF', '#BFDBFE')
}
.width('100%')
.padding(16)
.backgroundColor('#EFF6FF')
.borderRadius(8)
Column({ space: 12 }) {
this.sectionTitle('默认选中要有理由', '默认项不是随便勾一个。案例里默认选“标准模式”,因为它最稳,也最少惊扰用户。')
this.radioRow('轻量模式', '提示少一点,适合只想看重点的人。', 'mode', 'light', false, true,
'#0F766E', '#99F6E4', '#FFFFFF', '#CCFBF1')
this.radioRow('标准模式', '信息量适中,适合作为默认选择。', 'mode', 'standard', true, true,
'#0F766E', '#99F6E4', '#FFFFFF', '#CCFBF1')
this.radioRow('完整模式', '提示更多,适合需要盯细节的人。', 'mode', 'full', false, true,
'#0F766E', '#99F6E4', '#FFFFFF', '#CCFBF1')
}
.width('100%')
.padding(16)
.backgroundColor('#F0FDFA')
.borderRadius(8)
Column({ space: 12 }) {
this.sectionTitle('禁用态要说明不是没点准', '不能选的时候,旁边文案要解释原因,别只让圆点变灰。')
this.radioRow('企业统一策略', '当前账号由管理员统一配置,个人暂时不能修改。', 'policy', 'company', true, false,
'#64748B', '#CBD5E1', '#FFFFFF', '#CBD5E1')
this.radioRow('试用结束后开放', '正式开通后才可以切到这个选项。', 'policy', 'trial', false, false,
'#64748B', '#CBD5E1', '#FFFFFF', '#CBD5E1')
}
.width('100%')
.padding(16)
.backgroundColor('#F8FAFC')
.borderRadius(8)
}
.width('100%')
.padding(20)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
}
- 点赞
- 收藏
- 关注作者
评论(0)