查看: 81|回复: 1

鸿蒙验证码输入框两种实现方案详解:自定义键盘与系统键盘

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
在鸿蒙应用开发中,验证码输入框几乎是登录页或安全验证环节的标配。尽管 ArkUI 提供了标准的 TextInput 组件,但业务需求往往更精细:比如六个独立方框、输入一位自动跳转下一位、高亮当前选中态,甚至完全屏蔽系统键盘而使用自定义数字盘。针对这些场景,ArkUI 主要提供了两条技术路径:一是基于自定义键盘 + 隐藏 TextInput 的方案,适合对 UI 一致性要求极高、希望完全掌控键盘样式的场景;二是基于系统键盘 + inputMethod 框架的方案,利用原生输入法能力,开发成本更低且符合用户习惯。本文将深入拆解这两种实现逻辑,帮助你根据项目实际情况做出最优选择。

方案一:自定义键盘与焦点转移技巧

当你需要完全定制键盘样式(例如金融类 App 常见的安全键盘),或者希望避免系统键盘弹出时遮挡布局,自定义键盘方案是首选。其核心难点在于:如何让界面上展示的 Text 组件响应点击并拉起键盘,同时还能实时显示输入内容。

这个方案的巧妙之处在于“移花接木”。我们在页面上放置一个透明的、隐藏的 TextInput 组件,并将其绑定自定义键盘。界面上看到的六个验证码框,实际上是由六个 Text 组件渲染的。为了让点击 Text 能唤起键盘,我们需要利用 sendEventByKey 方法。当用户点击某个 Text 时,通过该方法将焦点事件转移给隐藏的 TextInput,从而触发软键盘弹出。
  1. // 隐藏的真实输入框
  2. TextInput({ controller: this.controller })
  3. .width('100%')
  4. .height(0)
  5. .opacity(0)
  6. .id('HiddenInput')
  7. .customKeyboard(this.CustomKeyboardBuilder()) // 绑定自定义键盘
  8. .onChange((value) => {
  9.   // 同步数据到展示层
  10.   this.codeTxt = value;
  11.   this.updateHighlight(value.length);
  12. })
  13. // 展示层的 Text 组件
  14. Text(this.codeTxt[index])
  15. .width(40)
  16. .height(40)
  17. .border(this.showMouse[index] ? activeBorder : normalBorder)
  18. .onClick(() => {
  19.   // 关键步骤:将焦点转移给隐藏的 TextInput
  20.   sendEventByKey('HiddenInput', 10, '');
  21. })
复制代码

为了实现“输入一位自动跳下一位”以及“当前位高亮”的效果,我们需要维护两个状态变量:codeTxt 存储完整的验证码字符串;showMouse 是一个布尔数组,用于标记哪一位处于激活(高亮)状态。在 onChange 回调或 @Watch 监听中,根据 codeTxt 的长度动态更新 showMouse 数组。当长度小于最大位数时,将对应索引设为 true,其余为 false;当输满时,全部取消高亮。这种数据驱动视图的方式,能确保 UI 状态与输入内容严格同步。

方案二:系统键盘与输入法框架监听

如果项目没有特殊的键盘定制需求,直接使用系统原生键盘不仅能减少代码量,还能让用户获得熟悉的输入体验。但直接使用 TextInput 往往难以实现“六个独立框”的视觉效果,因此我们需要借助 inputMethod 框架来“曲线救国”。

在这种方案下,页面上依然只放置六个 Text 组件用于展示,不再依赖 TextInput 进行数据绑定。取而代之的是,我们通过 inputMethod 模块直接控制输入法的显隐,并订阅其底层事件。首先,需要在页面可见时绑定输入法控制器,并配置为数字键盘模式:
  1. import inputMethod from '@ohos.inputMethod';
  2. async attachAndListener() {
  3.   const textConfig: inputMethod.TextConfig = {
  4.     inputAttribute: {
  5.       textInputType: inputMethod.TextInputType.NUMBER,
  6.       enterKeyType: inputMethod.EnterKeyType.GO
  7.     }
  8.   };
  9.   // 绑定输入法
  10.   await this.inputController.attach(true, textConfig);
  11.   this.attachListener();
  12. }
复制代码

绑定成功后,关键在于订阅 insertText 和 deleteLeft 事件。当用户在系统键盘上点击数字时,会触发 insertText 回调,我们将接收到的字符拼接到本地字符串变量中;当用户点击退格键时,deleteLeft 回调会被触发,此时截取字符串即可实现删除效果。
  1. attachListener(): void {
  2.   // 监听插入文本
  3.   this.inputController.on('insertText', (text) => {
  4.     if (this.codeTxt.length >= 6) return;
  5.     this.codeTxt += text;
  6.     this.updateUI(); // 刷新界面高亮
  7.   });
  8.   // 监听删除操作
  9.   this.inputController.on('deleteLeft', (length) => {
  10.     this.codeTxt = this.codeTxt.substring(0, this.codeTxt.length - 1);
  11.     this.updateUI();
  12.   });
  13. }
复制代码

此外,为了提升体验,通常还会结合 onVisibleAreaChange 监听组件可见性。当验证码区域完全进入可视区时自动拉起键盘,离开时自动解绑,避免资源浪费。

方案对比与落地建议

两种方案各有优劣,选择时需权衡开发成本与用户体验。自定义键盘方案的优势在于极致的可控性。你可以完全定义键盘的布局、颜色和动画,彻底规避系统键盘弹起导致的页面重排问题,特别适合对安全性或品牌 UI 有严格要求的场景。但其缺点也很明显:需要手动处理焦点转移、自行绘制键盘 UI,且无法享受系统输入法自带的纠错、语音输入等高级功能,开发工作量较大。

系统键盘方案则胜在轻量与原生体验。利用 inputMethod 框架,我们既保留了原生键盘的流畅度,又实现了自定义的 UI 展示。代码逻辑相对清晰,维护成本低,且天然支持多语言输入切换。唯一的局限是必须依赖系统键盘的存在,若系统键盘本身存在兼容性问题,可能会影响表现。

在实际落地中,如果是普通的 C 端应用登录页,推荐优先采用系统键盘方案,快速上线且体验稳定;若是银行、支付等对安全键盘有强制规范的场景,则自定义键盘方案是不二之选。无论哪种方式,核心都在于理清数据流与视图的映射关系,利用 ArkUI 的状态管理机制,让验证码输入过程既流畅又美观。
回复

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: 鸿蒙验证码输入框两种实现方案详解:自定义键盘与系统键盘

非常细致的分析,感谢分享!这两种方案正好覆盖了不同场景的需求。我尤其关注你提到的“移花接木”焦点转移技巧,用隐藏的TextInput配合自定义键盘,确实能在保证UI自由度的同时保持输入响应。另外,系统键盘方案中通过监听 insertText 和 deleteLeft 事件来同步数据,也很巧妙,比直接绑定 TextInput 更灵活。最后给出的选型建议也很务实,对于大多数C端应用,系统键盘方案确实更省心。收藏了,以后做验证码模块可以当参考。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-6-5 10:50 , Processed in 0.029627 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部