Harmony OS Next自定义键盘实现车牌输入

Harmony OS Next自定义键盘实现车牌输入

Laughing
2025-02-09 / 0 评论 / 10 阅读 / 正在检测是否收录...

爱车记App有一个我的车库功能,用户可以维护自己的车辆信息,包括车牌号码,为了方便输入车牌,可以通过自定义键盘的方式实现车牌号码的录入。
m6xmc9tc.png
m6xmcj0k.png

  //展示的text
  @State @Watch('setCarNumberText') carNumberText: string = "";
  //屏幕宽度
  @State screenWidth: number = 0;
  @State isShow: boolean = false
  @State inputValue: string = ""
  //车牌号最大长度
  @State carNumberMaxLength: number = 8;
  @State carNumberIndex: number[] = []
  //控制动画的
  @State showMouse: boolean[] = [];
  @State isFirstInput: boolean = true
  provincesKeyBoard: string[][] =
    [["京", "津", "晋", "冀", "蒙", "辽", "吉", "黑", "沪"], ["苏", "浙", "皖", "闽", "赣", "鲁", "豫", "鄂", "湘"],
      ["粤", "桂", "琼", "渝", "川", "贵", "云", "藏"],
      ["陕", "甘", "青", "宁", "新", "", getStringFromResource($r("app.string.item_key_delete"))]]
  commonKeys: string[][] =
    [["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"], ["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P"],
      ["A", "S", "D", "F", "G", "H", "J", "K", "L"], ["Z", "X", "C", "V", "B", "N", "M"],
      ["港", "澳", "学", getStringFromResource($r("app.string.item_key_delete"))]]
  commonKeyBoard: CommonKeyItem[][] = [[], [], [], [], []]
  // 输入框的大小
  inputBoxSize: number = 0
  controller: TextInputController = new TextInputController()
  //未选中的样式
  private btnCancelBorder?: commonBorder = { width: '3px', color: '#ccc', style: BorderStyle.Solid }
  //选中的样式
  private btnCancelBorderActive: commonBorder = { width: '3px', color: Color.Red, style: BorderStyle.Solid }


  build() {
  
        // 车牌
        Column() {
          Text($r("app.string.car_number"))
            .fontSize(10)
            .fontColor($r("app.color.label_font_color"))
            .alignSelf(ItemAlign.Start)
          this.carNumberComponentBuilder()
        }
        .justifyContent(FlexAlign.Start)
        .padding({ left: 15, right: 15 })
        .width('100%')
        .borderRadius(15)
        
  }
    }

  onPageShow(): void {
    //自定义键盘
    this.screenWidth = 1080;
    this.showMouse = new Array(this.carNumberMaxLength).fill(false);
    this.showMouse[0] = true
    for (let i = 0; i < this.carNumberMaxLength; i++) {
      this.carNumberIndex[i] = i
    }
    this.inputBoxSize = px2vp(this.screenWidth) / (this.carNumberIndex.length + 1) - 2
    for (let i = 0; i < this.commonKeys.length; i++) {
      for (let j = 0; j < this.commonKeys[i].length; j++) {
        this.commonKeyBoard[i][j] = new CommonKeyItem(this.commonKeys[i][j], true)
      }
    }

  
  }

 /**
   * 车牌号改变监听
   */
  setCarNumberText() {
    if (this.carNumberText.length == 0) {
      this.isFirstInput = true
    } else {
      this.isFirstInput = false
    }
    this.getForbiddenInput(this.carNumberText)
    this.handelInputTxt(this.carNumberText.length, this.carNumberText);
    this.myCar.number = this.carNumberText
  }

  //可以控制禁止输入的按键
  getForbiddenInput(input: string) {
    // if (input && input.length === 1) {
    //   this.commonKeyBoard[0][0].display = false
    //   this.commonKeyBoard[0][1].display = false
    //   this.commonKeyBoard[0][2].display = false
    //   this.commonKeyBoard[0][3].display = false
    //   this.commonKeyBoard[0][4].display = false
    //   this.commonKeyBoard[0][5].display = false
    //   this.commonKeyBoard[0][6].display = false
    //   this.commonKeyBoard[0][7].display = false
    //   this.commonKeyBoard[0][8].display = false
    //   this.commonKeyBoard[0][9].display = false
    //
    //   this.commonKeyBoard[4][0].display = false
    //   this.commonKeyBoard[4][1].display = false
    //   this.commonKeyBoard[4][2].display = false
    // } else if (input && input.length === 2) {
    //   this.commonKeyBoard[0][0].display = false
    //   this.commonKeyBoard[0][1].display = false
    //   this.commonKeyBoard[0][2].display = false
    //   this.commonKeyBoard[0][3].display = false
    //   this.commonKeyBoard[0][4].display = false
    //   this.commonKeyBoard[0][5].display = false
    //   this.commonKeyBoard[0][6].display = false
    //   this.commonKeyBoard[0][7].display = false
    //   this.commonKeyBoard[0][8].display = false
    //   this.commonKeyBoard[0][9].display = false
    //
    //   this.commonKeyBoard[1][0].display = false
    //   this.commonKeyBoard[1][1].display = false
    //   this.commonKeyBoard[1][2].display = true
    //   this.commonKeyBoard[1][3].display = false
    //   this.commonKeyBoard[1][4].display = false
    //   this.commonKeyBoard[1][5].display = false
    //   this.commonKeyBoard[1][6].display = false
    //   this.commonKeyBoard[1][7].display = false
    //   this.commonKeyBoard[1][8].display = false
    //   this.commonKeyBoard[1][9].display = false
    //
    //   this.commonKeyBoard[2][0].display = true
    //   this.commonKeyBoard[2][1].display = false
    //   this.commonKeyBoard[2][2].display = true
    //   this.commonKeyBoard[2][3].display = false
    //   this.commonKeyBoard[2][4].display = false
    //   this.commonKeyBoard[2][5].display = false
    //   this.commonKeyBoard[2][6].display = false
    //   this.commonKeyBoard[2][7].display = false
    //   this.commonKeyBoard[2][8].display = false
    //
    //   this.commonKeyBoard[3][0].display = true
    //   this.commonKeyBoard[3][1].display = false
    //   this.commonKeyBoard[3][2].display = true
    //   this.commonKeyBoard[3][3].display = false
    //   this.commonKeyBoard[3][4].display = true
    //   this.commonKeyBoard[3][5].display = false
    //   this.commonKeyBoard[3][6].display = false
    //
    //   this.commonKeyBoard[4][0].display = false
    //   this.commonKeyBoard[4][1].display = false
    //   this.commonKeyBoard[4][2].display = false
    // } else {
    //   this.commonKeyBoard[0][0].display = true
    //   this.commonKeyBoard[0][1].display = true
    //   this.commonKeyBoard[0][2].display = true
    //   this.commonKeyBoard[0][3].display = true
    //   this.commonKeyBoard[0][4].display = true
    //   this.commonKeyBoard[0][5].display = true
    //   this.commonKeyBoard[0][6].display = true
    //   this.commonKeyBoard[0][7].display = true
    //   this.commonKeyBoard[0][8].display = true
    //   this.commonKeyBoard[0][9].display = true
    //
    //   this.commonKeyBoard[1][0].display = true
    //   this.commonKeyBoard[1][1].display = true
    //   this.commonKeyBoard[1][2].display = true
    //   this.commonKeyBoard[1][3].display = true
    //   this.commonKeyBoard[1][4].display = true
    //   this.commonKeyBoard[1][5].display = true
    //   this.commonKeyBoard[1][6].display = true
    //   this.commonKeyBoard[1][7].display = true
    //   this.commonKeyBoard[1][8].display = true
    //   this.commonKeyBoard[1][9].display = true
    //
    //   this.commonKeyBoard[2][0].display = true
    //   this.commonKeyBoard[2][1].display = true
    //   this.commonKeyBoard[2][2].display = true
    //   this.commonKeyBoard[2][3].display = true
    //   this.commonKeyBoard[2][4].display = true
    //   this.commonKeyBoard[2][5].display = true
    //   this.commonKeyBoard[2][6].display = true
    //   this.commonKeyBoard[2][7].display = true
    //   this.commonKeyBoard[2][8].display = true
    //
    //   this.commonKeyBoard[3][0].display = true
    //   this.commonKeyBoard[3][1].display = true
    //   this.commonKeyBoard[3][2].display = true
    //   this.commonKeyBoard[3][3].display = true
    //   this.commonKeyBoard[3][4].display = true
    //   this.commonKeyBoard[3][5].display = true
    //   this.commonKeyBoard[3][6].display = true
    //
    //   this.commonKeyBoard[4][0].display = true
    //   this.commonKeyBoard[4][1].display = true
    //   this.commonKeyBoard[4][2].display = true
    // }
  }

  //改变输入框选中的值
  handelInputTxt(length: number, _val: string) {
    for (let i = 0; i < this.carNumberMaxLength; i++) {
      this.showMouse[i] = false
    }
    this.showMouse[length] = true
  }

  //自定义键盘样式
  @Builder
  CustomKeyboardBuilder() {
    Column() {
      if (this.isFirstInput) {
        this.buildProvinceKeyboard(this.provincesKeyBoard[0])
        this.buildProvinceKeyboard(this.provincesKeyBoard[1])
        this.buildProvinceKeyboard(this.provincesKeyBoard[2])
        this.buildProvinceKeyboard(this.provincesKeyBoard[3])
      } else {
        this.buildCommonKeyboard(this.commonKeyBoard[0])
        this.buildCommonKeyboard(this.commonKeyBoard[1])
        this.buildCommonKeyboard(this.commonKeyBoard[2])
        this.buildCommonKeyboard(this.commonKeyBoard[3])
        this.buildCommonKeyboard(this.commonKeyBoard[4])
      }
    }.backgroundColor(0xf0f0f0).padding({ bottom: px2vp(this.bottomRectHeight) })
  }

  @Builder
  buildCommonKeyboard(keyboard: CommonKeyItem[]) {
    Grid() {
      ForEach(keyboard, (item: CommonKeyItem) => {
        GridItem() {
          if (item.key === getStringFromResource($r("app.string.item_key_delete"))) {
            Text() {
              ImageSpan($r('app.media.custom_keyboard_delete'))
                .width('100px')
                .height('100px')
                .objectFit(ImageFit.Fill)
                .verticalAlign(ImageSpanAlignment.CENTER);
            }
            .fontSize(16)
            .textAlign(TextAlign.Center)
            .width(36)
            .height(40)
            .backgroundColor(Color.White)
            .borderRadius(4)
            .onClick(() => {
              this.carNumberText = this.carNumberText.slice(0, -1);
            });
          } else {
            if (item.display) {
              Text(item.key)
                .width(25)
                .backgroundColor(Color.White)
                .fontSize(16)
                .textAlign(TextAlign.Center)
                .width(35)
                .height(40)
                .backgroundColor(Color.White)
                .borderRadius(4)
                .onClick(() => {
                  if (this.carNumberText.length < this.carNumberMaxLength) {
                    this.carNumberText += item.key;
                  }
                });
            } else {
              Text(item.key)
                .width(25)
                .backgroundColor(Color.White)
                .fontSize(16)
                .textAlign(TextAlign.Center)
                .width(35)
                .height(40)
                .backgroundColor(0xE0E0f0)
                .borderRadius(4)
                .onClick(() => {

                });
            }
          }
        };
      });
    }.maxCount(keyboard.length).columnsGap(4).rowsGap(4).padding(3)
  }

  @Builder
  buildProvinceKeyboard(keyboard: string[]) {
    Grid() {
      ForEach(keyboard, (item: string) => {
        GridItem() {
          if (item == getStringFromResource($r("app.string.item_key_delete"))) {
            Text() {
              ImageSpan($r('app.media.custom_keyboard_delete'))
                .width('100px')
                .height('100px')
                .objectFit(ImageFit.Fill)
                .verticalAlign(ImageSpanAlignment.CENTER);
            }
            .fontSize(16)
            // .fontWeight(600)
            .textAlign(TextAlign.Center)
            .width(38)
            .height(40)
            .backgroundColor($r("app.color.white"))
            .borderRadius(4)
            .onClick(() => {
              this.carNumberText = this.carNumberText.slice(0, -1);
            });
          } else {
            Text(item)
              .fontSize(16)// .fontWeight(600)
              .textAlign(TextAlign.Center)
              .width(38)
              .height(40)
              .backgroundColor($r("app.color.white"))
              .borderRadius(4)
              .onClick(() => {
                if (!item) {
                  return
                }
                if (this.carNumberText.length < this.carNumberMaxLength) {
                  this.carNumberText += item;
                }
              });
          }
        };
      });
    }
    .maxCount(keyboard.length)
    .columnsGap(4)
    .rowsGap(4)
    .padding(3)
  }

  @Builder
  carNumberComponentBuilder() {
    Column() {
      this.buildCarNumberInput()
    }
  }

  //车牌号码构造器
  @Builder
  buildCarNumberInput() {
    Flex({
      direction: FlexDirection.Row,
      alignItems: ItemAlign.Center,
      justifyContent: FlexAlign.SpaceBetween
    }) {
      Column() {
        Row() {
          Text(this.carNumberText[0])
            .fontSize(16)
            .textAlign(TextAlign.Center)
            .width(this.inputBoxSize)
            .height(this.inputBoxSize)
            .margin({ left: 1, right: 1 })
            .border(this.showMouse[this.carNumberIndex[0]] ? this.btnCancelBorderActive : this.btnCancelBorder)
            .borderRadius(5)
          Text(this.carNumberText[1])
            .fontSize(16)
            .textAlign(TextAlign.Center)
            .width(this.inputBoxSize)
            .height(this.inputBoxSize)
            .margin({ left: 1, right: 1 })
            .border(this.showMouse[this.carNumberIndex[1]] ? this.btnCancelBorderActive : this.btnCancelBorder)
            .borderRadius(5)
          Text(this.carNumberText[2])
            .fontSize(16)
            .textAlign(TextAlign.Center)
            .width(this.inputBoxSize)
            .height(this.inputBoxSize)
            .margin({ left: 1, right: 1 })
            .border(this.showMouse[this.carNumberIndex[2]] ? this.btnCancelBorderActive : this.btnCancelBorder)
            .borderRadius(5)
          Text(this.carNumberText[3])
            .fontSize(16)
            .textAlign(TextAlign.Center)
            .width(this.inputBoxSize)
            .height(this.inputBoxSize)
            .margin({ left: 1, right: 1 })
            .border(this.showMouse[this.carNumberIndex[3]] ? this.btnCancelBorderActive : this.btnCancelBorder)
            .borderRadius(5)
          Text(this.carNumberText[4])
            .fontSize(16)
            .textAlign(TextAlign.Center)
            .width(this.inputBoxSize)
            .height(this.inputBoxSize)
            .margin({ left: 1, right: 1 })
            .border(this.showMouse[this.carNumberIndex[4]] ? this.btnCancelBorderActive : this.btnCancelBorder)
            .borderRadius(5)
          Text(this.carNumberText[5])
            .fontSize(16)
            .textAlign(TextAlign.Center)
            .width(this.inputBoxSize)
            .height(this.inputBoxSize)
            .margin({ left: 1, right: 1 })
            .border(this.showMouse[this.carNumberIndex[5]] ? this.btnCancelBorderActive : this.btnCancelBorder)
            .borderRadius(5)
          Text(this.carNumberText[6])
            .fontSize(16)
            .textAlign(TextAlign.Center)
            .width(this.inputBoxSize)
            .height(this.inputBoxSize)
            .margin({ left: 1, right: 1 })
            .border(this.showMouse[this.carNumberIndex[6]] ? this.btnCancelBorderActive : this.btnCancelBorder)
            .borderRadius(5)
          Text(this.carNumberText[7])
            .fontSize(16)
            .textAlign(TextAlign.Center)
            .width(this.inputBoxSize)
            .height(this.inputBoxSize)
            .margin({ left: 1, right: 1 })
            .border(this.showMouse[this.carNumberIndex[7]] ? this.btnCancelBorderActive : this.btnCancelBorder)
            .borderRadius(5)
        }
        .onClick(() => {
          focusControl.requestFocus('LicensePlateInput')
        }).width('100%').justifyContent(FlexAlign.SpaceBetween)

        TextInput()
          .width('100%')
          .height(250)
          .opacity(0)
          .id('LicensePlateInput')
          .enableKeyboardOnFocus(true)
          .customKeyboard(this.CustomKeyboardBuilder())
      }.width('100%')
    }
    .height(32)
    .id("customInput")
    .defaultFocus(false)
  }
}

export interface commonBorder {
  width?: Length | EdgeWidths,
  color?: ResourceColor | EdgeColors,
  radius?: Length | BorderRadiuses,
  style?: BorderStyle | EdgeStyles
}

class CommonKeyItem {
  key: string;
  display: boolean;

  constructor(key: string, display: boolean) {
    this.key = key;
    this.display = display
  }
}
  
0

评论 (0)

取消