export class NumberKeyBoardStyle { private static instance: NumberKeyBoardStyle //重写所有点击事件 慎用 参数一为下标 参数二为当前textInputValue的值 rebuildAllClick?: (_: string, __: number) => void private border: BorderOptions = { width: 1, color: '#FF1A7DD8' } private borderRadius: Length | BorderRadiuses | LocalizedBorderRadiuses = 6 private commonButtonBackgroundColor: ResourceColor = Color.White // 0的背景颜色 private zeroBackGround: ResourceColor = '#FFACD7FF' // 完成的背景颜色 private finishBackGround: ResourceColor = '#FF186EBD' // 删除按钮的图标 private deleteIcon: ResourceStr = $r('app.media.app_icon') // 完成按钮的text private finishText: ResourceStr = '完成' private rowsGap: Length = 4.62 private columnsGap: Length = 4.62 // 大按钮的高 private longHeight: Length = 101.69 // 普通按钮的高 private shortHeight: Length = 48.59 // 字体样式 private fontSize: number = 20 private fonsWeight: number = 500 private fontFamily: string = 'Source Han Sans SC' constructor() { if (!NumberKeyBoardStyle.instance) { NumberKeyBoardStyle.instance = this } return NumberKeyBoardStyle.instance } getFontSize() { return this.fontSize } setFontSize(fontSize: number) { this.fontSize = fontSize return this } getFontWeight() { return this.fonsWeight } setFontWeight(fontWeight: number) { this.fonsWeight = fontWeight return this } getFontFamily() { return this.fontFamily } setFontFamily(fontFamily: string) { this.fontFamily = fontFamily return this } getShortHeight() { return this.shortHeight } setShortHeight(height: Length) { this.shortHeight = height return this } getLongHeight() { return this.longHeight } setLongHeight(height: Length) { this.longHeight = height return this } getRowsGap() { return this.rowsGap } setColumnsGap(columnsGap: number) { this.columnsGap = columnsGap return this } setRowsGap(rowsGap: number) { this.rowsGap = rowsGap return this } getColumnsGap() { return this.columnsGap } getBorder() { return this.border } setBorder(border: BorderOptions) { this.border = border return this } getBorderRadius() { return this.borderRadius } setBorderRadius(borderRadius: Length | BorderRadiuses | LocalizedBorderRadiuses) { this.borderRadius = borderRadius return this } getZeroBackGround() { return this.zeroBackGround } setZeroBackGround(zeroBackGround: ResourceColor) { this.zeroBackGround = zeroBackGround return this } getFinishBackGround() { return this.finishBackGround } setFinishBackGround(finishBackGround: ResourceColor) { this.finishBackGround = finishBackGround return this } getDeleteIcon() { return this.deleteIcon } setDeleteIcon(deleteIcon: ResourceStr) { this.deleteIcon = deleteIcon return this } getCommonButtonBackground() { return this.commonButtonBackgroundColor } setCommonButtonBackground(commonButtonBackground: ResourceColor) { this.commonButtonBackgroundColor = commonButtonBackground return this } getFinishText() { return this.finishText } setFinishText(finishText: ResourceStr) { this.finishText = finishText return this } } @Extend(Text) function TextStyle(style: NumberKeyBoardStyle) { .fontSize(style.getFontSize()) .fontWeight(style.getFontWeight()) .fontFamily(style.getFontFamily()) } /** * @description 自定义数字按钮键盘 */ @Component export struct NumberKeyBoard { //初始值 @Prop @Require textInputValue: string //最大输入数 maxInputNum: number = 5 //样式设置 支持链式设置 允许动态修改 但是如果在父组件使用链式调用需要重新赋值,因为链式调用会导致装饰器失效 @Prop keyBoardStyle: NumberKeyBoardStyle //完成字体的样式 自己实现AttributeModifier来传 AttributeModifier不支持响应式 如果需要动态刷新需要同步更改其它具有响应式的属性 textModifier?: AttributeModifier //grid计算器的排序规则 private layoutOptions: GridLayoutOptions = { regularSize: [1, 1], irregularIndexes: Array.from({ length: 13 }).map((_, index) => index), onGetIrregularSizeByIndex: (index: number) => { if (index < 10) { if (index == 3) { return [2, 3] } return [1, 3] } else if (index == 10) { return [2, 3] } else if (index == 11) { return [1, 4] } else { return [1, 5] } } }; //点击完成所需要的逻辑 onFinishClick = (_: string) => { } //输入值变化 onTextInputValueChange = (_: string) => { } @Styles pressStyles() { .opacity(0.7) } @Styles normalStyles() { .opacity(1) } build() { Grid(undefined, this.layoutOptions) { ForEach(Array.from({ length: 13 }), (_: undefined, index) => { GridItem() { Column() { if (index == 3) { Image(this.keyBoardStyle.getDeleteIcon()) .width(20) .aspectRatio(2) } else if (index == 10) { Text(this.keyBoardStyle.getFinishText()) .TextStyle(this.keyBoardStyle) .attributeModifier(this.textModifier) } else if (index == 11) { Text('0') .TextStyle(this.keyBoardStyle) } else if (index == 12) { Text('.') .TextStyle(this.keyBoardStyle) } else if (index < 3) { Text((index + 1).toString()) .TextStyle(this.keyBoardStyle) } else { Text(index.toString()) .TextStyle(this.keyBoardStyle) } } .backgroundColor(index == 11 ? this.keyBoardStyle.getZeroBackGround() : index == 10 ? this.keyBoardStyle.getFinishBackGround() : this.keyBoardStyle.getCommonButtonBackground()) .width('100%') .height(this.calcGridItemHeight(index)) .borderRadius(this.keyBoardStyle.getBorderRadius()) .justifyContent(FlexAlign.Center) .border(this.keyBoardStyle.getBorder()) .stateStyles({ pressed: this.pressStyles, normal: this.normalStyles }) .onClick(() => { if (this.keyBoardStyle.rebuildAllClick) { this.keyBoardStyle.rebuildAllClick(this.textInputValue, index) return } if (index == 3) { if (this.textInputValue.length > 0) { this.textInputValue = this.textInputValue.slice(0, this.textInputValue.length - 1) } if (this.textInputValue == '') { this.textInputValue = '0' } this.onTextInputValueChange(this.textInputValue) return } if (index == 10) { this.onFinishClick(this.textInputValue) return } if (this.textInputValue.length >= this.maxInputNum) { if (this.textInputValue.length > this.maxInputNum) { //裁剪为最大长度 this.textInputValue = this.textInputValue.slice(0, this.maxInputNum) } return } if (index == 11) { if (parseInt(this.textInputValue) > 0) { this.textInputValue = this.textInputValue.concat('0') } } else if (index == 12) { if (!this.textInputValue.includes('.')) { this.textInputValue = this.textInputValue.concat('.') } } else if (index < 3) { if (parseInt(this.textInputValue) > 0) { this.textInputValue = this.textInputValue.concat((index + 1).toString()) } else { this.textInputValue = (index + 1).toString() } } else { if (parseInt(this.textInputValue) > 0|| this.textInputValue.includes('.')) { this.textInputValue = this.textInputValue.concat(index.toString()) } else { this.textInputValue = index.toString() } } this.onTextInputValueChange(this.textInputValue) }) } }) } .rowsGap(this.keyBoardStyle.getRowsGap()) .columnsGap(this.keyBoardStyle.getColumnsGap()) .columnsTemplate('repeat(12, 1fr)') // .layoutWeight(1) .width('100%') } //计算渲染grid的高 private calcGridItemHeight(index: number): Length { if (index == 3 || index == 10) { return this.keyBoardStyle.getLongHeight() } else { return this.keyBoardStyle.getShortHeight() } } }