鸿蒙ArkUI封装的复选组件,官方提供了复选组件,不方便多选项列表复用,我们为此进行了封装。支持点击标签文本选中,其中显示选中非选中采用图片的方式。
import {IDynamicObject} from './IType' /** * 复选 */ @Component export default struct DiygwCheckbox{ //绑定的值 @Link @Watch('onValue') value:string[]; // 保存所有单选框的名称 @Link list: IDynamicObject[]; // 隐藏值 @State valueField: string = 'value'; // 显示值 @State labelField: string = 'label'; // 选中/未选中状态下的图标 @State checkedValues: Resource[] = []; //选中图标 @State checkedImg: Resource = $r('app.media.checkboxon'); //未选中图标 @State noCheckedImg: Resource = $r('app.media.checkbox'); //未选中图标 @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 labelColor:string = "#333333"; //自动标题长度 @State isLabelAuto:boolean = false; //文本字体大小 @State textSize:number = 14; //选中图版本大小 @State imgSize:number = 28; //每个占比 @State itemWidth:string = '33%'; //每行个数 @State col:number = 3; //组件内边距 @State leftRightPadding:number = 16; @State topBottomPadding:number = 6; @State isBorder:boolean = true; //初始化选中 initCheck(){ for (let i = 0; i < this.list.length; i++) { if(this.value.includes(this.list[i][this.valueField])) { this.checkedValues[i] = this.checkedImg; }else{ this.checkedValues[i] = this.noCheckedImg; } } } //监听选中 onValue() { this.initCheck() } onChecked(index: number){ //点击文本选中当前复选框 if(this.checkedValues[index]==this.checkedImg){ this.checkedValues[index] = this.noCheckedImg let findIndex = this.value.indexOf(this.list[index][this.valueField]); this.value.splice(findIndex,1); }else{ this.checkedValues[index] = this.checkedImg; this.value.push(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 }).flexShrink(0) } if(this.isLabelAuto){ Text(this.label).flexShrink(0).fontColor(this.labelColor).fontSize(this.textSize).margin({ bottom:this.isWrapLabel?10:0, right:10, }).textAlign(TextAlign.Start); }else{ Text(this.label).fontColor(this.labelColor).width(this.isWrapLabel?'100%':this.labelWidth).fontSize(this.textSize).margin({ bottom:this.isWrapLabel?10:0 }).textAlign(TextAlign.Start); } }.margin({ top:this.isWrapLabel?10:0 }) } 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%') }.borderWidth({ bottom: this.isBorder?1:0 }).borderColor({ bottom: "#eee" }).borderStyle(BorderStyle.Solid).height(Math.ceil(this.list.length/this.col)*30+(this.isWrapLabel?30:10)+this.topBottomPadding*2).padding({left:this.leftRightPadding,right:this.leftRightPadding,top:this.topBottomPadding,bottom:this.topBottomPadding}) .onAppear(() => { let widths=['100%','50%','33%','25%'] let col = widths.indexOf(this.itemWidth) + 1 this.col = col this.initCheck() }) } }