场景描述

场景一:基于自定义键盘的验证码实现,进入页面后直接输入验证码,第一个验证码输入完后可自动跳到下一个,拉起的键盘是自定义数字键盘,验证码的输入框带选中效果。

场景二:基于系统键盘的验证码实现,进入页面后直接输入验证码,第一个验证码输入完后可自动跳到下一个,验证码的输入框带选中效果。

方案描述

场景一

基于自定义键盘的验证码实现,进入页面后直接输入验证码,第一个验证码输入完后可自动跳到下一个,拉起的键盘是自定义数字键盘,验证码的输入框带选中效果。

方案

1.每个验证码都是通过text实现的,而不是textInput。

2.在页面中写一个textInput将其隐藏,通过sendEventByKey方法将textInput的点击事件转移给text,同时给textInput绑定自定义键盘,这样点击text即可拉起自定义键盘。

3.将输入框的值赋值给text,通过text将其展示出来。

核心代码

1.写一个TextInput将其隐藏,给TextInput设置id后,在Text的点击事件中通过sendEventByKey方法将TextInput的点击事件转移到Text上,这样就可以点击Text拉起软键盘。

2.在onChange中对codeTxt进行赋值,将输入框的值赋给codeTxt,再通过codeTxt的下标进行展示。

3.对codeTxt进行监听,showMouse是一个布尔类型的数组,当前验证码处于输入状态时,将其值改为true,这样就可改变输入框的选中状态。

//展示在页面上的文本 
@State @Watch('setValue') codeTxt: string = ''; 
@State Index: number[] = [0, 1, 2, 3, 4, 5] 
//控制选中文本样式 
@State showMouse: boolean[] = []; 
 
@Builder 
buildAEnterCodeInput() { 
  Flex({ 
    direction: FlexDirection.Row, 
    alignItems: ItemAlign.Center, 
    justifyContent: FlexAlign.SpaceBetween 
  }) { 
    Column(){ 
      Row(){ 
        //text将拿到的值进行逐个展示 
        Text(this.codeTxt[0]) 
          .fontSize(18) 
          .fontWeight(600) 
          .textAlign(TextAlign.Center) 
          .width(50) 
          .height(50) 
          .margin({ left: 5, right: 5 })// .border({ width: 0.5, color:  Color.Grey ,style: BorderStyle.Solid }) 
            //设置验证码选中的样式 
          .border(this.showMouse[this.Index[0]] ? this.btnCancelBorderActive : this.btnCancelBorder) 
          .borderRadius(5) 
        …… 
      } 
      .onClick(()=>{ 
        //通过sendEventByKey方法将输入框的点击事件转移给text 
        sendEventByKey('TextInput',10,'') 
      }) 
      //写一个输入框,将其隐藏 
      TextInput({ controller: this.controller }) 
        .width('100%') 
        .height(100)// .zIndex(1) 
        .opacity(0) 
        .id('TextInput') 
        .customKeyboard(this.CustomKeyboardBuilder()) 
        .onChange((value) => { 
          //将隐藏的输入框的value值赋值给codeTxt  
          this.codeTxt = value 
          if (this.codeTxt.length >= 6) { 
            return 
          } 
        }) 
    } 
  } 
  .backgroundColor(Color.White) 
  .height(50) 
  .margin({ left: 15, right: 15 }) 
  .id("customInput") 
  .defaultFocus(false) 
} 
//对codeTxt进行监听, 
setValue() { 
  if (this.codeTxt) { 
    this.handelInputTxt(this.codeTxt.length, this.codeTxt); 
  } else { 
    this.handelInputTxt(0, ''); 
  } 
} 
 
//改变输入框选中的值,showMouse是一个布尔类型的数组,当前验证码处于输入状态时,将其值改为true 
handelInputTxt(length: number, val: string) { 
  length === this.maxLength ? this.showMouse.fill(false) : this.showMouse.fill(false).splice(length - 1, 0, true); 
  console.log('----length', length) 
  console.info("----this.showMouse", JSON.stringify(this.showMouse)); 
}

设置的公共页面,点击即可拉起半模态。

//公共页面,点击即可拉起半模态 
@Builder 
buildTitleName() { 
  CommonPage() 
    .onClick(() => { 
      //模态弹窗是否展示 
      this.isShow = true 
    }) 
    .bindSheet($$this.isShow, this.bindSheetBuilder, { 
      height: '70%', 
      // detents:[SheetSize.MEDIUM,SheetSize.LARGE,500], 
      // backgroundColor:Color.Gray, 
      blurStyle: BlurStyle.Thick, 
      showClose: false, 
      // title:{title:""}, 
      preferType: SheetType.CENTER 
    }) 
  ……

场景二

基于系统键盘的验证码实现,进入页面后直接输入验证码,第一个验证码输入完后可自动跳到下一个,验证码的输入框带选中效果。

方案

1.验证码均是通过六个text实现。

2.通过输入法框架拉起系统键盘,对系统键盘进行监听,即可做到输入和删除的效果。

3.进行条件判断,符合条件时就对输入法进行绑定和监听,否则就解绑输入法。

核心代码

展示在页面上的六个Text,通过输入法框架拉起键盘。

@Builder 
buildAEnterCodeInput() { 
  Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceBetween }) { 
    Text(this.codeTxt[0]) 
      .fontSize(18) 
      .fontWeight(600) 
      .textAlign(TextAlign.Center) 
      .width((this.screenWidth - 110) / 6) 
      .height("100%") 
      .margin({ left: 5, right: 5 }) 
      .border({ 
        width: 0.5, 
        color:  Color.Grey , 
        style: BorderStyle.Solid 
      }) 
      .borderRadius(5) 
  } 
  .backgroundColor(Color.White) 
  .height(50) 
  .margin({ left: 15, right: 15 }) 
  .id("customInput") 
  .defaultFocus(false) 
  .onVisibleAreaChange([0.0, 1.0], (isVisible: boolean, currentRatio: number) => { 
    if (isVisible && currentRatio >= 1.0) { 
      //绑定输入法 
      this.attachAndListener(); 
    } 
    if (!isVisible && currentRatio <= 0.0) { 
      //解绑输入法 
      this.dettach() 
    } 
  }) 
  //点击即通过输入法的控制拉起键盘 
  .onClick(async () => { 
    if (this.isAttached && this.keyboardStatus != 2) { 
      // 输入法配置项 
      let textConfig: inputMethod.TextConfig = { 
        inputAttribute: { 
          textInputType: inputMethod.TextInputType.NUMBER, 
          enterKeyType: inputMethod.EnterKeyType.GO 
        } 
      }; 
 
      // 控件绑定输入法 
      await this.inputController.attach(true, textConfig) 
      return 
    } 
  }) 
}

实现思路:对输入法进行绑定和监听,通过输入法框架拉起软键盘,可以订阅输入法应用插入、删除文本事件等。

//解绑输入法 
dettach() { 
  this.inputController.off('insertText'); 
  this.inputController.off('deleteLeft'); 
  this.inputController.off('sendKeyboardStatus'); 
  this.inputController.detach((err: BusinessError) => { 
    if (err) { 
      console.error(`Failed to detach: ${JSON.stringify(err)}`); 
      return; 
    } 
    this.isAttached = false 
    console.log('Succeeded in detaching inputMethod.'); 
  }); 
} 
 
// 绑定和设置监听 
async attachAndListener() { 
  // 输入法配置项 
  let textConfig: inputMethod.TextConfig = { 
    inputAttribute: { 
      //拉起数字键盘 
      textInputType: inputMethod.TextInputType.NUMBER, 
      enterKeyType: inputMethod.EnterKeyType.GO 
    } 
  }; 
 
  // 控件绑定输入法 
  await this.inputController.attach(true, textConfig) 
  this.isAttached = true 
  this.attachListener() 
} 
 
/** 
 * 订阅输入法回调 
 */ 
attachListener(): void { 
  // 订阅输入法应用插入文本事件 
  this.inputController.on('insertText', (text) => { 
    if (this.codeTxt.length >= 6) { 
      return 
    }   
    this.codeTxt += text; 
    console.info("this.inputText", "insertText this.inputText===" + this.codeTxt) 
  }) 
 
  // 订阅输入法应用向左删除事件 
  this.inputController.on('deleteLeft', (length) => { 
    this.codeTxt = this.codeTxt.substring(0, this.codeTxt.length - 1); 
    console.info("this.inputText", "deleteLeft  this.inputText===" + this.codeTxt,'length'+length) 
  }) 
 
  // 订阅输入法应用发送输入法软键盘状态事件 
  this.inputController.on('sendKeyboardStatus', (keyboardStatus: inputMethod.KeyboardStatus) => { 
    this.keyboardStatus = keyboardStatus 
    console.info("ImsaKit this.inputText keyboardStatus= " + this.keyboardStatus) 
  }) 
}

HarmonyOS码上奇行
7.5k 声望2.9k 粉丝