仿京东短信验证码UI效果(鸿蒙)

整体思路:

外层Stack布局,里面TextInput组件用来调起键盘,Row布局中循环出四个Text组件,Row布局覆盖在TextInput组件上,用来展示输入的数字。

定义两个参数,code用来接受输入的文本,someArray用来做为想要展示的Text组件数量,其中的数字用来和code的长度做比较,来区分输入框是否写入文本。

ini 复制代码
  @State code: string = ''
  someArray: number[] = [1, 2, 3, 4]

这里循环someArray,Text组件未填入时显示 '-'并且即将写入数字的Text组件有橙色高亮,当四个输入框都有数字时,最后一个框高亮。

typescript 复制代码
Row() {
        ForEach(this.someArray, (item: number, index: number) => {
          if (item != 1) {
            Blank() // 除了第一个TextView自定义组件以外,其他三个的左边都添加一个Blank()组件
          }
          if (this.code.length >= item) {
            // 填过数字的输入框才满足这个条件, 且只有填到最后一个数字的时候isBorder才为true
            this.codeOne({ code: this.code.substring(item - 1, item), isBorder: item == 4 })
          } else {
            // 未填数字的输入框,显示'-',并且即将要输入的框为橙色
            this.codeOne({ code: '-', isBorder: this.code.length + 1 == item })
          }
        }, (item: number) => JSON.stringify(item))
      }
      .hitTestBehavior(HitTestMode.Transparent)
      .zIndex(2)
      .padding({ left: 16, right: 16 })
      .width('100%')
      
scss 复制代码
  @Builder
  codeOne($$: SMSInfo) {
    Text($$.code)
      .textAlign(TextAlign.Center)
      .width(60)
      .height(60)
      .border({ radius: 11, width: 3 })
      .borderColor($$.isBorder ? '#FF5500' : Color.Transparent)
      .backgroundColor('#F3F5F7')
  }

难点:需要事件透传,在Row布局上设置.hitTestBehavior(HitTestMode.Transparent),hitTestBehavior自身和子节点都响应触摸测试,不会阻塞兄弟节点的触摸测试。不会影响祖先节点的触摸测试。

完整代码:

typescript 复制代码
import { promptAction } from "@kit.ArkUI"

@Entry
@Component
export struct SMSCaptchaPage {
  @State code: string = ''
  someArray: number[] = [1, 2, 3, 4]

  build() {
    Stack() {
      Row() {
        ForEach(this.someArray, (item: number, index: number) => {
          if (item != 1) {
            Blank() // 除了第一个TextView自定义组件以外,其他三个的左边都添加一个Blank()组件
          }
          if (this.code.length >= item) {
            // 填过数字的输入框才满足这个条件, 且只有填到最后一个数字的时候isBorder才为true
            this.codeOne({ code: this.code.substring(item - 1, item), isBorder: item == 4 })
          } else {
            // 未填数字的输入框,显示'-',并且即将要输入的框为橙色
            this.codeOne({ code: '-', isBorder: this.code.length + 1 == item })
          }
        }, (item: number) => JSON.stringify(item))
      }
      .hitTestBehavior(HitTestMode.Transparent)
      .zIndex(2)
      .padding({ left: 16, right: 16 })
      .width('100%')

      TextInput()
        .width('100%')
        .height(50)
        .maxLength(4)
        .type(InputType.Number)
        .backgroundColor(Color.Transparent)
        .onChange((value: string) => {
          this.code = value // 输入的内容改变时, 实时的传给code
          if (value.length == 4) {
            promptAction.showToast({ message: '验证码输入成功,等待验证' })
          }
        })
    }
    .width('100%')
    .height('100%')
  }

  @Builder
  codeOne($$: SMSInfo) {
    Text($$.code)
      .textAlign(TextAlign.Center)
      .width(60)
      .height(60)
      .border({ radius: 11, width: 3 })
      .borderColor($$.isBorder ? '#FF5500' : Color.Transparent)
      .backgroundColor('#F3F5F7')
  }
}

class SMSInfo {
  code: string = ''
  isBorder: boolean = false
}
相关推荐
Kevin Coding6 小时前
JsonConvert:适用于 Android、鸿蒙与 Flutter 的 JSON 转 Model 插件
android·flutter·harmonyos
m0_749690238 小时前
【寻迹校园 HarmonyOS NEXT 实战 28】不交换手机号也能交接:固定校内交接点的隐私设计
华为·harmonyos·arkts·产品设计·隐私设计·安全交接
Magic-ZYJ8 小时前
HarmonyOS Stage 模型实战:UIAbility 生命周期如何驱动页面安全状态
安全·华为·harmonyos·鸿蒙·移动端开发·独立开发者·心晴手记
贾伟康8 小时前
【中国方言题库|09】HarmonyOS ArkTS 方言搜索实战:实现词语检索和无结果反馈
harmonyos·arkts·状态管理·arkui·本地搜索
Dovis(誓平步青云)9 小时前
从手机单栏到平板分栏:任务清单的筛选、选中态与不可变更新
华为·harmonyos
梦想不只是梦与想9 小时前
鸿蒙 AppGallery Connect:查看应用信息(三)
harmonyos·appgallery·client id·app id·developer id
贾伟康10 小时前
【中国方言题库|03】HarmonyOS ArkTS 四川话分库实战:复用题库组件并保持地区参数清晰
harmonyos·arkts·arkui·路由传参·组件复用
贾伟康10 小时前
【中国方言题库|10】HarmonyOS ArkTS 语音播放实战:管理读音播放与页面生命周期
生命周期·harmonyos·arkts·语音合成·texttospeech
YM52e21 小时前
鸿蒙ArkTS实战项目 - 门店陈列巡检台:巡检卡片与多列切换实现
学习·华为·harmonyos
lilian2331 天前
Harmony os 技术实战|拼豆制图27:用单字符编码承载 50 张 70×70 图纸
前端·数据库·华为·harmonyos