Radio是单选框组件,通常用于提供相应的用户交互选择项,同一组的Radio中只有一个可以被选中。
ArkUI创建一个单选框,其中value是单选框的名称,group是单选框的所属群组名称。checked属性可以设置单选框的状态,状态分别为false和true时,设置为true时表示单选框被选中。Radio仅支持选中和未选中两种样式,不支持自定义颜色和形状。
Radio({ value: 'Radio1', group: 'radioGroup' })
.checked(false)
Radio({ value: 'Radio2', group: 'radioGroup' })
.checked(true)
当使用的时,发现不是很友好,没有对应的文本,而且点击事件不方便选中单选框。
DIY可视化低代码鸿蒙开发发现使用过程非常得不方便,至此我们封装了一套自己的单选框组件,其中单选框用了图片来表示显中不显中,而且还增加了标签。非常得方便。
import {DynamicObject} from './type'
/**
* 自定义颜色
*/
@Component
export default struct DiygwRadio{
//绑定的值
@Link @Watch('onValue') value:string;
// 保存所有单选框的名称
@State list: DynamicObject[] = [];
// 隐藏值
@State valueField: string = 'value';
// 显示值
@State labelField: string = 'label';
// 选中/未选中状态下的图标
@State checkedValues: Resource[] = [];
//选中图标
@State checkedImg: Resource = $r('app.media.radioon');
//未选中图标
@State noCheckedImg: Resource = $r('app.media.radio');
//未选中图标
@State labelImg: Resource = $r('app.media.user');
//是否文本图片
@State isLabelImg: boolean = false;
@State labelImgWidth: number = 20;
@State labelImgHeight: number = 20;
//标题文本
@State label:string = '单选';
//水平状态时,文本占大小
@State labelWidth:number = 80;
//是否标题文本换行
@State isWrapLabel:boolean = true;
//是否标题文本
@State isLabel:boolean = true;
//文本字体大小
@State textSize:number = 14;
//选中图版本大小
@State imgSize:number = 28;
//每个占比
@State itemWidth:string = '33%';
//组件内边距
@State formPadding:number = 5;
//初始化选中
initCheck(){
for (let i = 0; i < this.list.length; i++) {
if(this.list[i][this.valueField] == this.value) {
this.checkedValues[i] = this.checkedImg;
}else{
this.checkedValues[i] = this.noCheckedImg;
}
}
}
//监听选中
onValue() {
this.initCheck()
}
onChecked(index: number){
//点击文本选中当前单选框
for (let i = 0; i < this.list.length; i++) {
this.checkedValues[i] = this.noCheckedImg;
}
this.checkedValues[index] = this.checkedImg;
this.value = this.list[index][this.valueField];
}
build() {
Flex({
alignItems:this.isWrapLabel?ItemAlign.Start:ItemAlign.Center,
direction:this.isWrapLabel?FlexDirection.Column:FlexDirection.Row,
justifyContent:FlexAlign.Start
}){
if(this.isLabel){
Row(){
if(this.isLabelImg){
Image(this.labelImg)
.width(this.labelImgWidth)
.height(this.labelImgHeight)
.margin({ left:3 })
}
Text(this.label).width(this.isWrapLabel?'100%':this.labelWidth).fontSize(this.textSize).margin({
bottom:this.isWrapLabel?15:0
}).textAlign(TextAlign.Start);
}
}
Flex({
wrap:FlexWrap.Wrap
}){
ForEach(this.list, (item: any,index: number) => {
Row(){
Image(this.checkedValues[index])
.borderRadius('50%')
.size({width: this.imgSize , height: this.imgSize}).margin({
top:1,
bottom:1
})
Text(item[this.labelField])
.fontSize(this.textSize)
.margin({left: 10})
}.onClick(()=>{
this.onChecked(index)
}).width(this.itemWidth)
})
}.width('100%')
}.padding(this.formPadding)
.onAppear(() => {
this.initCheck()
})
}
}
DiygwRadio({
itemWidth:'50%',
value: $radio,
list: [{
value: 'radio1',
label: '单选1'
}, {
value: 'radio2',
label: '单选2'
}, {
value: 'radio3',
label: '单选3'
}, {
value: 'radio21',
label: '单选2'
}, {
value: 'radio31',
label: '单选3'
}]
}).backgroundColor('#fff').margin(10).borderRadius(5)
DiygwRadio({
value: $radio,
itemWidth:'50%',
valueField: 'value1',
labelField: 'label1',
list: [{
value1: 'radio1',
label1: '单选1'
}, {
value1: 'radio2',
label1: '单选2'
}, {
value1: 'radio3',
label1: '单选3'
}]
}).backgroundColor('#fff').margin(10).borderRadius(5)
DiygwRadio({
value: $radio,
itemWidth:'100%',
valueField: 'value1',
labelField: 'label1',
list: [{
value1: 'radio1',
label1: '单选1'
}, {
value1: 'radio2',
label1: '单选2'
}, {
value1: 'radio3',
label1: '单选3'
}]
}).backgroundColor('#fff').margin(10).borderRadius(5)