#跟着坚果学鸿蒙#

在实现验证码输入功能时,最初的思路是使用6个独立的TextInput组件来分别处理每个字符的输入。然而,这种方法存在一个明显的问题:当某个TextInput为空时,无法监听到删除事件。这使得用户体验不够流畅,因此我们决定放弃这种实现方式。

当前思路具体步骤如下:

首先,在底层创建一个TextInput组件,其长、宽和透明度都设置为0。这个TextInput组件将作为实际的输入框,用于接收用户的输入。由于它是透明的,用户不会直接看到它。

接下来,在这个透明的TextInput组件上覆盖N个Text组件。这里的N取决于验证码的长度。例如,如果验证码长度为6,那么我们就需要6个Text组件。这些Text组件将用于显示用户输入的每个字符。

当用户进入验证码输入页面或点击任意一个Text组件时,我们将透明的TextInput组件设置为聚焦状态。这样,用户的输入将直接进入这个透明的TextInput组件,而不是单独的Text组件。

为了确保用户输入的字符能够正确显示,我们需要根据当前输入的文本长度来切换和展示对应的Text样式。具体来说,当用户输入一个字符时,我们会更新第一个Text组件的内容;当用户输入第二个字符时,我们会更新第二个Text组件的内容,依此类推。

这种实现方式有几个显著的优点:

  1. 用户体验流畅:由于所有输入都集中在一个TextInput组件中,我们可以更容易地监听和处理删除事件,从而提供更流畅的用户体验。

  2. 样式统一:通过覆盖多个Text组件,我们可以更灵活地控制每个字符的样式,使其在视觉上更加统一和美观。

  3. 易于扩展:这种方法可以轻松适应不同长度的验证码,只需调整Text组件的数量即可。

  4. 代码简洁:相比于使用多个独立的TextInput组件,这种方法使代码更加简洁和易于维护。

@Entry
@Component
struct Login {
  @State code: string = '';
  @State showCode: string[] = new Array(6).fill('');
  
  @Builder
  codeLogin() {
    Column() {
      Text('请输入验证码')
        .width(280)
        .fontSize(18)
        .margin({ top: -80 })
      Text('验证码短信已发至:188 xxxx 6351')
        .width(280)
        .fontSize(14)
        .fontColor($r('app.color.grey'))
        .margin({ bottom: 105 })
      TextInput({ text: $$this.code })
        .width(0)
        .height(0)
        .maxLength(6)
        .type(InputType.Number)
        .key('sms-code')
        .opacity(0)
        .defaultFocus(true)

      Row({ space: 10 }) {
        ForEach(this.showCode, (item: string, index) => {
          Text(String(this.code[index] || ''))
            .key(String(index))
            .width(38)
            .height(59)
            .padding({ top: 15, bottom: 15 })
            .fontColor(this.code.length === index || (this.code.length === this.showCode.length && this.code.length - 1 === index) ? $r('app.color.primary_color') : 0X000000)
            .textAlign(TextAlign.Center)
            .border({
              width: 1,
              color: this.code.length === index || (this.code.length === this.showCode.length && this.code.length - 1 === index) ? $r('app.color.primary_color') : $r('app.color.border_color')
            })
            .borderWidth({ left: 0, top: 0, right: 0 })
            .onClick(() => {
              focusControl.requestFocus('sms-code')
            })
        }, (item: string, index) => String(index))
      }
    }
  }

  build() {
    this.codeLogin()
  }
}
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐