HarmonyOS 鸿蒙Next封装一个验证码输入框
HarmonyOS 鸿蒙Next封装一个验证码输入框
在实现验证码输入功能时,最初的思路是使用6个独立的TextInput组件来分别处理每个字符的输入。然而,这种方法存在一个明显的问题:当某个TextInput为空时,无法监听到删除事件。这使得用户体验不够流畅,因此我们决定放弃这种实现方式。
当前思路具体步骤如下:
首先,在底层创建一个TextInput组件,其长、宽和透明度都设置为0。这个TextInput组件将作为实际的输入框,用于接收用户的输入。由于它是透明的,用户不会直接看到它。
接下来,在这个透明的TextInput组件上覆盖N个Text组件。这里的N取决于验证码的长度。例如,如果验证码长度为6,那么我们就需要6个Text组件。这些Text组件将用于显示用户输入的每个字符。
当用户进入验证码输入页面或点击任意一个Text组件时,我们将透明的TextInput组件设置为聚焦状态。这样,用户的输入将直接进入这个透明的TextInput组件,而不是单独的Text组件。
为了确保用户输入的字符能够正确显示,我们需要根据当前输入的文本长度来切换和展示对应的Text样式。具体来说,当用户输入一个字符时,我们会更新第一个Text组件的内容;当用户输入第二个字符时,我们会更新第二个Text组件的内容,依此类推。
这种实现方式有几个显著的优点:
-
用户体验流畅:由于所有输入都集中在一个TextInput组件中,我们可以更容易地监听和处理删除事件,从而提供更流畅的用户体验。
-
样式统一:通过覆盖多个Text组件,我们可以更灵活地控制每个字符的样式,使其在视觉上更加统一和美观。
-
易于扩展:这种方法可以轻松适应不同长度的验证码,只需调整Text组件的数量即可。
-
代码简洁:相比于使用多个独立的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) => {
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 && <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 && <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(() => {
focusControl.requestFocus(<span class="hljs-string"><span class="hljs-string">'sms-code'</span></span>)
})
}, (item: string, index) => <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 联系官网客服。
是APP启动马上触发吗?是的话有可能是因为组件初始化未完成就触发了聚焦事件,可以延迟执行试试
有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html
这个只是一个验证码输入框,不包含短信发送相关,可以自行选择平台,比如阿里云或者腾讯云
我用的uniCloud
那里把云函数URL化后用request请求试试