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)