鸿蒙Radio是单选框组件,通常用于提供相应的用户交互选择项,同一组的Radio中只有一个可以被选中。 ArkUI创建一个单选框,其中value是单选框的名称,group是单选框的所属群组名称。checked属性可以设置单选框的状态,状态分别为false和true时,设置为true时表示单选框被选中。Radio仅支持选中和未选中两种样式,不支持自定义颜色和形状。
Radio({ value: 'Radio1', group: 'radioGroup' }) .checked(false)
Radio({ value: 'Radio2', group: 'radioGroup' }) .checked(true)
当使用的时,发现不是很友好,没有对应的文本,而且点击事件不方便选中单选框。
`
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 = false;
//是否标题文本
@State isLabel:boolean = true;
//文本字体大小
@State textSize:number = 14;
//选中图版本大小
@State imgSize:number = 28;
//每个占比
@State itemWidth:string = '33%';
//每行个数
@State col:number = 3;
//组件内边距
@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?10: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%')
}.height(Math.ceil(this.list.length/this.col)*38+(this.isWrapLabel?18:0)).padding(this.formPadding)
.onAppear(() => {
let widths=['100%','50%','33%','25%']
let col = widths.indexOf(this.itemWidth) + 1
this.col = col
this.initCheck()
})
}
}
`