HarmonyOS 鸿蒙Next自定义输入键盘

发布于 1周前 作者 wuwangju 来自 鸿蒙OS

HarmonyOS 鸿蒙Next自定义输入键盘

自定义输入键盘DEMO

2 回复
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
  }
}
@Entry
@Component
struct CustomKeyboard {
  //展示的text
  @State @Watch('setValue') codeTxt: string = "";
  //屏幕宽度
  @State screenWidth: number = 0;
  @State isShow: boolean = false
  @State inputValue: string = ""
  //最大长度
  @State maxLength: number = 7;
  //@State Index: number[] = [0, 1, 2, 3, 4, 5, 6]
  @State Index: number[] = []
  //控制动画的
  @State showMouse: boolean[] = [];
  @State isFirstInput: boolean = true
  @State isNewEngine:boolean = false
  // provincesKeyBoard: string[] = ["皖","京","津","渝","沪","冀","晋","辽","吉","黑","苏","浙","闽","赣","鲁","豫","鄂","湘",
  // "粤","琼","川","贵","云","陕","甘","青","蒙","桂","宁","新","藏","删"]
  provincesKeyBoard:string[][] = [["皖","京","津","渝","沪","冀","晋","辽","吉"], ["黑","苏","浙","闽","赣","鲁","豫","鄂","湘"],
    ["粤","琼","川","贵","云","陕","甘","青"], ["蒙","桂","宁","新","藏","删"]]
  // 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","港","澳","学", "删"]
  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"], ["港","澳","学", "删"]]
  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 }
  aboutToAppear(): void {
    console.info('IsaKit aboutToAppear')
    this.screenWidth = 1080;
    this.showMouse = new Array(this.maxLength).fill(false);
    this.showMouse[0] = true
    for (let i=0; i<this.maxLength; i++) {
      this.Index[i] = i
    }
    this.inputBoxSize = px2vp(this.screenWidth) / (this.Index.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)
      }
    }
  }
  setValue() {
    if (this.codeTxt.length == 0) {
      this.isFirstInput = true
    } else {
      this.isFirstInput = false
    }
    this.getForbiddenInput(this.codeTxt)
    this.handelInputTxt(this.codeTxt.length, this.codeTxt);
  }
  // TODO 根据前面的输入判断禁止输入的内容, 这里的禁止的按键只是展示
  getForbiddenInput(input:string) {
    this.commonKeyBoard[0][0].display = false
    this.commonKeyBoard[4][0].display = false
    this.commonKeyBoard[4][1].display = false
    this.commonKeyBoard[4][2].display = false
  }
  //改变输入框选中的值
  handelInputTxt(length: number, val: string) {
    length === this.maxLength ? this.showMouse.fill(false) : this.showMouse.fill(false).splice(length, 0, true);
    console.log('----length', length)
    console.info("----this.showMouse", JSON.stringify(this.showMouse));
    console.log('---value', val)
  }
  //自定义键盘样式
  @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)
  }
  @Builder
  buildCommonKeyboard(keyboard: CommonKeyItem[]) {
    Grid() {
      ForEach(keyboard, (item: CommonKeyItem) => {
        GridItem() {
          if (item.key == "删") {
            Text() {
              ImageSpan($r('app.media.arrow'))
                .width('100px')
                .height('100px')
                .objectFit(ImageFit.Fill)
                .verticalAlign(ImageSpanAlignment.CENTER);
            }
            .fontSize(18)
            .fontWeight(600)
            .textAlign(TextAlign.Center)
            .width(36)
            .height(50)
            .backgroundColor(Color.White)
            .borderRadius(3)
            .onClick(() => {
              this.codeTxt = this.codeTxt.slice(0, -1);
              console.info("this.inputText", "deleteLeft this.inputText===" + this.codeTxt);
            });
          } else {
            if (item.display) {
              Text(item.key)
                .width(25)
                .backgroundColor(Color.White)
                .fontSize(18)
                .fontWeight(600)
                .textAlign(TextAlign.Center)
                .width(35)
                .height(50)
                .backgroundColor(Color.White)
                .borderRadius(3)
                .onClick(() => {
                  if (this.codeTxt.length >= this.maxLength) {
                    console.info("超过最大长度");
                  } else {
                    this.codeTxt += item.key;
                  }
                });
            } else {
              Text(item.key)
                .width(25)
                .backgroundColor(Color.White)
                .fontSize(18)
                .fontWeight(600)
                .textAlign(TextAlign.Center)
                .width(35)
                .height(50)
                .backgroundColor(0xE0E0f0)
                .borderRadius(3)
                .onClick(() => {
                  console.info("按键禁止输入");
                });
            }
          }
        };
      });
    }.maxCount(keyboard.length).columnsGap(2).rowsGap(2).padding(2)
  }
  @Builder
  buildProvinceKeyboard(keyboard:string[]) {
    Grid() {
      ForEach(keyboard, (item: string) => {
        GridItem() {
          if (item == "删") {
            Text() {
              ImageSpan($r('app.media.ic_pin_selected'))
                .width('100px')
                .height('100px')
                .objectFit(ImageFit.Fill)
                .verticalAlign(ImageSpanAlignment.CENTER);
            }
            .fontSize(18)
            .fontWeight(600)
            .textAlign(TextAlign.Center)
            .width(38)
            .height(50)
            .backgroundColor(Color.White)
            .borderRadius(3)
            .onClick(() => {
              this.codeTxt = this.codeTxt.slice(0, -1);
              console.info("this.inputText", "deleteLeft this.inputText===" + this.codeTxt);
            });
          } else {
            Text(item)
              .fontSize(18)
              .fontWeight(600)
              .textAlign(TextAlign.Center)
              .width(38)
              .height(50)
              .backgroundColor(Color.White)
              .borderRadius(3)
              .onClick(() => {
                this.codeTxt += item;
              });
          }
        };
      });
    }.maxCount(keyboard.length).columnsGap(2).rowsGap(2).padding(2)
  }
  @Builder
  componentBuilder() {
    Column() {
      Blank().height(100)
      this.buildAEnterCodeInput()
      //Blank().height(20).backgroundColor(Color.Black)
    }
    .margin({ top: 10 })
    .borderRadius(8)
  }
  //验证码的样式
  @Builder
  buildAEnterCodeInput() {
    Flex({
      direction: FlexDirection.Row,
      alignItems: ItemAlign.Center,
      justifyContent: FlexAlign.SpaceBetween
    }) {
      Column() {
        Row(){
          Text("车牌号码")
        }.height(30)
        Row() {
          Text(this.codeTxt[0])
            .fontSize(18)
            .fontWeight(600)
            .textAlign(TextAlign.Center)
            .width(this.inputBoxSize)
            .height(this.inputBoxSize)
            .margin({ left: 1, right: 1 })
            .border(this.showMouse[this.Index[0]] ? this.btnCancelBorderActive : this.btnCancelBorder)
            .borderRadius(5)
          Text(this.codeTxt[1])
            .fontSize(18)
            .fontWeight(600)
            .textAlign(TextAlign.Center)
            .width(this.inputBoxSize)
            .height(this.inputBoxSize)
            .margin({ left: 1, right: 1 })
            .border(this.showMouse[this.Index[1]] ? this.btnCancelBorderActive : this.btnCancelBorder)
            .borderRadius(5)
          Text('.')
            .fontSize(22)
            .fontWeight(600)
            .textAlign(TextAlign.Center)
              // .width(this.inputBoxSize-5)
              // .height(this.inputBoxSize-5)
            .margin({ left: 1, right: 1 })
          Text(this.codeTxt[2])
            .fontSize(18)
            .fontWeight(600)
            .textAlign(TextAlign.Center)
            .width(this.inputBoxSize)
            .height(this.inputBoxSize)
            .margin({ left: 1, right: 1 })
            .border(this.showMouse[this.Index[2]] ? this.btnCancelBorderActive : this.btnCancelBorder)
            .borderRadius(5)
          Text(this.codeTxt[3])
            .fontSize(18)
            .fontWeight(600)
            .textAlign(TextAlign.Center)
            .width(this.inputBoxSize)
            .height(this.inputBoxSize)
            .margin({ left: 1, right: 1 })
            .border(this.showMouse[this.Index[3]] ? this.btnCancelBorderActive : this.btnCancelBorder)
            .borderRadius(5)
          Text(this.codeTxt[4])
            .fontSize(18)
            .fontWeight(600)
            .textAlign(TextAlign.Center)
            .width(this.inputBoxSize)
            .height(this.inputBoxSize)
            .margin({ left: 1, right: 1 })
            .border(this.showMouse[this.Index[4]] ? this.btnCancelBorderActive : this.btnCancelBorder)
            .borderRadius(5)
          Text(this.codeTxt[5])
            .fontSize(18)
            .fontWeight(600)
            .textAlign(TextAlign.Center)
            .width(this.inputBoxSize)
            .height(this.inputBoxSize)
            .margin({ left: 1, right: 1 })
            .border(this.showMouse[this.Index[5]] ? this.btnCancelBorderActive : this.btnCancelBorder)
            .borderRadius(5)
          Text(this.codeTxt[6])
            .fontSize(18)
            .fontWeight(600)
            .textAlign(TextAlign.Center)
            .width(this.inputBoxSize)
            .height(this.inputBoxSize)
            .margin({ left: 1, right: 1 })
            .border(this.showMouse[this.Index[6]] ? this.btnCancelBorderActive : this.btnCancelBorder)
            .borderRadius(5)
          Text("新能源")
            .fontSize(10)
            .fontWeight(600)
            .textAlign(TextAlign.Center)
            .width(this.inputBoxSize)
            .height(this.inputBoxSize)
            .margin({ left: 1, right: 1 })
            .border(this.isNewEngine ? this.btnCancelBorderActive : this.btnCancelBorder)
            .borderRadius(5)
            .fontColor(Color.Blue)
            .onClick(()=>{
              this.isNewEngine = !this.isNewEngine
            })
        }
        .margin({top: 20, bottom: 20})
        .onClick(() => {
          // sendEventByKey('TextInput', 10, '')
          focusControl.requestFocus('LicensePlateInput')
          console.log("点击了整个row 获取焦点");
        })
        TextInput()
          .width('100%')
          .height(250)
          .opacity(0)
          .id('LicensePlateInput')
          .customKeyboard(this.CustomKeyboardBuilder())
        // .onChange((value) => {
        // this.codeTxt = value
        // if (this.codeTxt.length >= 7) {
        // return
        // }
        // this.codeTxt += this.inputValue;
        // console.info("----codeTxt" + this.codeTxt)
        // })
      }
    }
    .backgroundColor(Color.White)
    .height(50)
    .margin({ left: 15, right: 15 })
    .id("customInput")
    .defaultFocus(false)
  }
  build() {
    Column() {
      this.componentBuilder()
    }
  }
}

针对HarmonyOS 鸿蒙Next自定义输入键盘的问题,以下是一些专业解答:

HarmonyOS 鸿蒙Next支持自定义输入键盘的开发与集成,这为用户提供了更加个性化和安全的输入体验。在开发自定义键盘时,开发者需要注意以下几点:

  1. 键盘布局与功能:自定义键盘的布局应合理,功能应完善,包括字母、数字、符号等常用按键,以及必要的切换和删除操作。
  2. 输入逻辑与光标管理:优化输入逻辑,确保在高速输入时也能准确控制光标位置。同时,正确处理焦点转移,避免在切换键盘时出现光标位置异常的情况。
  3. 安全性与隐私保护:对于涉及敏感信息(如密码)的输入场景,应使用安全键盘,并确保用户输入的数据得到妥善保护。
  4. 兼容性与稳定性:确保自定义键盘与HarmonyOS系统的其他组件和API兼容,并进行充分的测试以确保其稳定性。

如果开发者在开发过程中遇到具体问题,可以参考HarmonyOS的官方文档和开发者社区的资源进行解决。如果问题依旧没法解决,请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部