Radio是單選框組件,通常用於提供相應的用戶交互選擇項,同一組的Radio中隻有一個可以被選中。
ArkUI創建一個單選框,其中value是單選框的名稱,group是單選框的所屬群組名稱。checked屬性可以設置單選框的狀態,狀態分別為false和true時,設置為true時表示單選框被選中。Radio僅支持選中和未選中兩種樣式,不支持自定義顏色和形狀。
Radio({ value: 'Radio1', group: 'radioGroup' }).checked(false)
Radio({ value: 'Radio2', group: 'radioGroup' }).checked(true)
當使用的時,發現不是很友好,沒有對應的文本,而且點擊事件不方便選中單選框。
如果在我們常用表單中,需要用到單選組件復用的情況,使用起來相當不方便。所以封裝了一個單選Radio組件。
![](https://news.xinpengboligang.com/upload/keji/4b559add7967b48dc2e4bb3a0d07d2ff.jpeg)
![](https://news.xinpengboligang.com/upload/keji/af9c7b35a34fd8d6b6b08c3bb45a5ad7.jpeg)
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()
})
}
}
組件使用代碼
DiygwRadio({
isWrapLabel:true,
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)