鸿蒙开发:一个简单的滑块验证组件

前言

防黑产一直是互联网坚持在做的安全事项,为了防止程序攻击,可以说大部分应用都存在一定的安全验证,比如验证码、指纹验证,图形码识别,拖动滑块验证等等,其目的也显而易见,就是建立一道"人机防火墙",通过要求用户完成一个对人类简单、对机器困难的交互,来有效识别和拦截自动化程序,从而守护程序安全,今天就给大家带来其中的一个简单的验证场景,那就是拖动滑块验证。

拖动滑块验证,可以说,简单便捷,也是常见安全验证中最经典、最常用的一种交互形式,它主要用于拦截自动化脚本的非真人操作,区分人类用户和机器程序,从而保护程序安全,当然了,任何一个程序,都不是百分之百的安全,前几天的快手事件就是一个特例,所以滑块验证只能作为前端的一种简单的拦截方式。

实现效果

当然了,可以自定义定义样式,如下所示:

那么,这样的一个从左滑动到右边的拖动滑块验证,如何实现呢?其实实现起来也是非常的简单,通过绑定手势gesture,便可以轻松实现。

如何实现

实现方式有多种,无非就是两层视图,底部的默认视图,和顶部的滑动视图,我们需要注意的是,顶部的滑动视图,如果,你要采用的是偏移量的方式,也就是先让滑块平移到屏幕外,然后滑动时慢慢的展示,需要注意组件的宽度设置。

以上的方式并不是不推荐,如果是组件和屏幕宽度一致,这时是没有问题的,但是实际当中的组件,是任意位置摆放的,如果还按照偏移量的方式,就会让滑块提前展示,显然是不允许的,所以这一点,需要注意。

一开始,我也是采用的上面的方式,确实实现了效果,但是,固定宽度之后,还需要处理滑块的展示位置,于是,就改成了另一种实现方式,那就是,滑块的宽度默认为0,然后随着手势移动,逐渐增加滑块的宽度,这种方式,就不会存在滑块展示的问题。

TypeScript 复制代码
//中间的滑层
Column() {
  if (this.sliderView != undefined) {
    this.sliderView()
  } else {
    Column() {

    }.width("100%")
      .height(this.sHeight)
      .border(this.sliderAttribute?.sliderViewAttr?.border)
      .backgroundColor(this.sliderAttribute?.sliderViewAttr?.backgroundColor != undefined ?
                       this.sliderAttribute?.sliderViewAttr?.backgroundColor : "#5abc3c")
  }
}
.width(this._privateOffsetWidth)
  .height(this.sHeight)
  .alignItems(HorizontalAlign.Start)
  .animation({ duration: this._privateDuration })

解决完滑块的问题之后,还有一个需要解决,那就是文字颜色的改变,我们可以发现,在滑动的时候,文字颜色是灰色的,慢慢滑动之后,滑过的文字就会变成白色,而未滑过的文字还是灰色,这是如何实现的呢?

很简单,采用的是两个Text组件,底部的灰色Text,我们不需要改变,主要是顶部的滑块Text文字颜色,这里处理的方式是逐字加载,使用Span组件,根据滑动的距离,分别来更改文字颜色。

TypeScript 复制代码
ForEach(this.sTextArray, (t: string, index: number) => {
  Span(t)
    .fontColor(this._privateChangeTextColorArray[index])
    .fontSize(14)
    .fontStyle(this.sliderAttribute?.completeTextAttr?.fontStyle)
    .fontWeight(this.sliderAttribute?.completeTextAttr?.fontWeight)
})

滑动逻辑

滑动上没什么好说的,只监听左右滑动即可,随着手势滑动,不断的改变顶部滑动视图的宽度,如果松手未到右边,就还原初始值,如果到最右边,就回调完成,更改滑块状态。

TypeScript 复制代码
.gesture(
  PanGesture({ distance: 1, direction: PanDirection.Left | PanDirection.Right })
  .onActionStart(() => {
    this._privateDuration = 0
  })
  .onActionUpdate((event: GestureEvent) => {
    //赋值滑块偏移量,必须大于0
    if (event.offsetX > 0) {
      if (event.offsetX > (this._privateWindowWidth - Number(this.thumbWidth))) {
        this._privateThumbOffsetX = this._privateWindowWidth - Number(this.thumbWidth)
        //状态完成时回调
        if (this.onComplete != undefined && !this._privateIsScrollComplete) {
          this._privateIsScrollComplete = true
          this._privateOffsetWidth = this._privateThumbOffsetX
          this.onComplete()
        }
      } else {
        this._privateIsScrollComplete = false
        this._privateOffsetWidth = event.offsetX
        this._privateThumbOffsetX = event.offsetX

      }
    } else {
      this._privateThumbOffsetX = 0
      this._privateOffsetWidth = 0
    }
    //改变文字颜色
    this.changeTextColor(event.offsetX)


  })
  .onActionEnd(() => {
    //滑动结束
    this.changeCompleteStatus()
  })
)

快速使用

为了方便大家使用,目前已经封装好了组件,上传到了中心仓库,大家有需要可以直接使用。

中心仓库地址:

ohpm.openharmony.cn/#/cn/detail...

快速依赖

方式一:在Terminal窗口中,执行如下命令安装三方包,DevEco Studio会自动在工程的oh-package.json5中自动添加三方包依赖。

建议:在使用的模块路径下进行执行命令。

TypeScript 复制代码
ohpm install @abner/slider

方式二:在需要的模块中的oh-package.json5中设置三方包依赖,配置示例如下:

TypeScript 复制代码
"dependencies": { "@abner/slider": "^1.0.0"}

代码使用

目前默认的是常规的绿色验证样式,如果符合需求,可以直接使用。

TypeScript 复制代码
SliderDragView({
  onComplete: () => {
    //滑动完成
    console.log("=======滑动完成")
  }
})

自定义组件形式

目前支持所有的样式自定义,需要自己来逐一实现自己需要的UI。

TypeScript 复制代码
SliderDragView({
  sText: "拖动滑块滑动",
  sCompleteText: "完成验证",
  defaultView: () => {
    //自定义默认视图
    this.defaultView()
  },
  sliderView: () => {
    //自定义滑动视图
    this.sliderView()
  },
  thumbSlidingView: () => {
    //自定义滑块滑动中视图
    this.thumbSlidingView()
  },
  thumbCompleteView: () => {
    //自定义滑块完成视图
    this.thumbCompleteView()
  },
  onComplete: () => {
    //滑动完成
    console.log("=======滑动完成")
  }
}).margin({ top: 20 })

完整案例

TypeScript 复制代码
import { SliderControl, SliderDragView } from '@abner/slider'

@Entry
  @Component
  struct SliderPage {
    sliderControl: SliderControl = new SliderControl()
    sliderControl2: SliderControl = new SliderControl()

    @Builder
    defaultView() {
      Column() {
        Text("拖动滑块滑动")
          .fontSize(14)
      }
      .width("100%")
        .height("100%")
        .justifyContent(FlexAlign.Center)
        .backgroundColor(Color.Pink)
        .borderRadius(10)
    }

    @Builder
    sliderView() {
      Column() {

      }.width("100%")
        .height("100%")
        .backgroundColor(Color.Red)
        .borderRadius({ topLeft: 10, bottomLeft: 10 })
    }

    @Builder
    thumbSlidingView() {
      Text("-->")
        .width("100%")
        .height("100%")
        .backgroundColor(Color.White)
        .textAlign(TextAlign.Center)
        .borderRadius({ topRight: 10, bottomRight: 10 })
        .border({ width: 1, color: "#e8e8e8" })
    }

    @Builder
    thumbCompleteView() {
      Column() {
        SymbolGlyph($r('sys.symbol.checkmark_circle_fill'))
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .renderingStrategy(SymbolRenderingStrategy.SINGLE)
          .fontColor([Color.Red])
      }
      .width("100%")
        .height("100%")
        .backgroundColor(Color.White)
        .justifyContent(FlexAlign.Center)
        .borderRadius({ topRight: 10, bottomRight: 10 })
        .border({ width: 1, color: "#e8e8e8" })
    }

    build() {
      Column() {
        SliderDragView({
          sliderControl: this.sliderControl,
          onComplete: () => {
            //滑动完成
            console.log("=======滑动完成")
          }
        })

        //全部自定义

        SliderDragView({
          sText: "拖动滑块滑动",
          sCompleteText: "完成验证",
          sliderControl: this.sliderControl2,
          defaultView: () => {
            //自定义默认视图
            this.defaultView()
          },
          sliderView: () => {
            //自定义滑动视图
            this.sliderView()
          },
          thumbSlidingView: () => {
            //自定义滑块滑动中视图
            this.thumbSlidingView()
          },
          thumbCompleteView: () => {
            //自定义滑块完成视图
            this.thumbCompleteView()
          },
          onComplete: () => {
            //滑动完成
            console.log("=======滑动完成")
          }
        }).margin({ top: 20 })

        Button("重置")
          .margin({ top: 20 })
          .onClick(() => {
            this.sliderControl.reset()
            this.sliderControl2.reset()
          })
      }
      .height('100%')
        .width('100%')
        .padding({ left: 20, right: 20 })
        .justifyContent(FlexAlign.Center)
    }
  }

相关属性

属性 类型 概述
sWidth Length 整体组件的宽度
sHeight Length 整体组件的高度
thumbWidth Length 滑块的宽度
thumbHeight Length 滑块的高度
defaultView @BuilderParam 自定义传递的默认视图
sliderView @BuilderParam 自定义传递的拖动视图
thumbSlidingView @BuilderParam 拖动的滑块-滑动中视图
thumbCompleteView @BuilderParam 拖动的滑块-滑动完成
sDuration number 手指结束时的动画时间,默认100毫秒
onComplete () => void 滑动完成状态回调
sText string 提示内容, 默认为:按住滑块拖动
sCompleteText string 滑动完成提示内容,默认为:完成验证
sliderControl SliderControl 重置控制器,可还原滑动状态
sliderAttribute SliderDragAttribute 默认滑动视图属性,如果自己定义组件,则不需要

SliderDragAttribute

滑动视图默认属性,如果是使用的自定义组件形式,此属性配置无效。

属性 类型 概述
defaultViewAttr DefaultViewAttribute 默认的视图属性
sliderViewAttr SliderViewAttribute 滑动的视图属性
completeTextAttr CompleteTextAttribute 完成文字属性
thumbCompleteAttr ThumbCompleteAttribute 滑块完成属性
thumbSlidingAttr ThumbCompleteAttribute 滑块滑动属性

相关总结

一个很常见的滑块验证组件,本身并不难,如果有需要,大家可以直接使用,希望可以帮助到你,还是那句话,滑块验证只能作为一个简单的安全验证,它不是绝对安全的,这一点,大家需要知道。

相关推荐
王家视频教程图书馆13 小时前
android java播放器依赖
android
robotx16 小时前
安卓16屏保中的启用时机,选项不正确
android
JulyYu16 小时前
【Android】第三方库依赖引发的异常情况排查
android·android studio
游戏技术分享17 小时前
【鸿蒙游戏技术分享 第75期】AGC后台批量导入商品失败,提示“参数错误”
游戏·华为·harmonyos
No Silver Bullet18 小时前
HarmonyOS NEXT开发进阶(十七):WebView 拉起 H5 页面
华为·harmonyos
liuhaikang18 小时前
【鸿蒙HarmonyOS Next App实战开发】口语小搭档——应用技术实践
harmonyos
QING61818 小时前
简单说下Kotlin 作用域函数中 apply 和 also 为什么不能空安全调用?
android·kotlin·android jetpack
城东米粉儿19 小时前
着色器 (Shader) 的基本概念和 GLSL 语法 笔记
android
儿歌八万首21 小时前
Jetpack Compose :封装 MVVM 框架
android·kotlin·compose
2501_9159214321 小时前
iOS App 中 SSL Pinning 场景下代理抓包失效的原因
android·网络协议·ios·小程序·uni-app·iphone·ssl