HarmonyOS 鸿蒙Next封装一个验证码输入框

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

HarmonyOS 鸿蒙Next封装一个验证码输入框

在实现验证码输入功能时,最初的思路是使用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: <span class="hljs-number"><span class="hljs-number">10</span></span> }) {
    ForEach(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.showCode, (item: string, index) =&gt; {
      Text(<span class="hljs-built_in"><span class="hljs-built_in">String</span></span>(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.code[index] || <span class="hljs-string"><span class="hljs-string">''</span></span>))
        .key(<span class="hljs-built_in"><span class="hljs-built_in">String</span></span>(index))
        .width(<span class="hljs-number"><span class="hljs-number">38</span></span>)
        .height(<span class="hljs-number"><span class="hljs-number">59</span></span>)
        .padding({ top: <span class="hljs-number"><span class="hljs-number">15</span></span>, bottom: <span class="hljs-number"><span class="hljs-number">15</span></span> })
        .fontColor(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.code.length === index || (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.code.length === <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.showCode.length &amp;&amp; <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.code.length - <span class="hljs-number"><span class="hljs-number">1</span></span> === index) ? $r(<span class="hljs-string"><span class="hljs-string">'app.color.primary_color'</span></span>) : <span class="hljs-number"><span class="hljs-number">0X000000</span></span>)
        .textAlign(TextAlign.Center)
        .border({
          width: <span class="hljs-number"><span class="hljs-number">1</span></span>,
          color: <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.code.length === index || (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.code.length === <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.showCode.length &amp;&amp; <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.code.length - <span class="hljs-number"><span class="hljs-number">1</span></span> === index) ? $r(<span class="hljs-string"><span class="hljs-string">'app.color.primary_color'</span></span>) : $r(<span class="hljs-string"><span class="hljs-string">'app.color.border_color'</span></span>)
        })
        .borderWidth({ left: <span class="hljs-number"><span class="hljs-number">0</span></span>, top: <span class="hljs-number"><span class="hljs-number">0</span></span>, right: <span class="hljs-number"><span class="hljs-number">0</span></span> })
        .onClick(() =&gt; {
          focusControl.requestFocus(<span class="hljs-string"><span class="hljs-string">'sms-code'</span></span>)
        })
    }, (item: string, index) =&gt; <span class="hljs-built_in"><span class="hljs-built_in">String</span></span>(index))
  }
}

}

build() { this.codeLogin() } }<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>



关于HarmonyOS 鸿蒙Next封装一个验证码输入框的问题,您也可以访问:https://www.itying.com/category-93-b0.html 联系官网客服。

7 回复
您好,我用focusControl.requestFocus的时候,遇到一个问题。app启动以后偶尔会有调用requestFocus方法后TextInput获取不到焦点的情况,不知道你遇到过这个问题没有啊

是APP启动马上触发吗?是的话有可能是因为组件初始化未完成就触发了聚焦事件,可以延迟执行试试

有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html

你发送短信验证码用的什么接口,云开发的云函数吗?

这个只是一个验证码输入框,不包含短信发送相关,可以自行选择平台,比如阿里云或者腾讯云

我用的uniCloud

那里把云函数URL化后用request请求试试

回到顶部