Flutter 手势指纹解锁

背景

  在最近做的一个Flutter项目中,需要用到手势、指纹解锁,这种需求在原生应用中非常常见,但Flutter中手势密码解锁现有库比较少、官方也仅提供有一个 local_auth指纹库,所以就自己写了个手势库。

功能属性

  • 支持自定义各状态下(常态、操作时、操作出错时、不可用时)线颜色、填充色和线宽;
  • 支持自定义各种状态下(常态、操作时、操作出错时、不可用时)每个圆圈样式和连接线样式;
  • 支持实心、空心两种样式
  • 支持图案绘制完成后延迟 500毫秒(默认值)自动清除;
  • 支持指示器辅助控件可选择使用;
  • 业务逻辑(至少连点几个点、验证时最多可出错几次等)可自定义。

实现效果

image

思路

  其实实现这个自定义的手势控件有很多思路,首先想到的是,要在View中创建9个圆,那么使用GridView再合适不过了,但是经过尝试,放弃了,这会使交互跟逻辑变的更加复杂,所以还是选择直接继承Widget,自己处理逻辑与手势,那么下面就是需要处理的逻辑:

  1. 根据控件的大小,绘制9个圆圈;
  2. 在手指按到圆圈时,开始绘制路线,并且将按下的圆圈置为选中状态;
  3. 在手指滑动时,绘制一根跟随手指移动的、起点为按下的圆圈的线;
  4. 当手指滑动到另外一个圆圈时,将第一个按下的圆圈与当前圆圈用线连起来,并且绘制一根以当前圆圈为起点的跟随手指移动的线;
  5. 手指按下到圆圈时,以及每次划过圆圈时,将此圆圈对应的数字添加到数组;
  6. 当手指抬起时,根据添加的数字判断密码是否正确,若错误,则将所有的线、选中的圆,都置为错误的状态、颜色;
  7. 当超过错误次数不可用时,将圆设为不可用状态、颜色,且不可滑动;

代码结构

类名 描述
GestureUnlockView 手势绘制区域、包括9个圆圈、手势操作、自定义属性等
UnlockPointPainter 圆圈绘制类
UnlockPoint 圆圈属性类
UnlockLinePainter 连接线绘制类
GestureUnlockIndicator 辅助指示器类

支持属性

属性名 作用 默认值
size 整个控件大小
type 圆圈类型 实心
padding 与父 widget 边距 10
roundSpace 圆圈之间的间距
roundSpaceRatio 圆圈之间的间距比例(以圆半径作为基准),[roundSpace]设置时无效 0.6
defaultColor 常态时颜色 Colors.grey
selectedColor 操作时选中颜色 Colors.blue
failedColor 操作出错时颜色 Colors.blue
disableColor 不可用时颜色 Colors.grey
lineWidth 连接线宽度 2
solidRadiusRatio 实心圆半径比例(以圆半径作为基准) 0.4
touchRadiusRatio 触摸有效区半径比例(以圆半径作为基准) 0.6
delayTime 延迟还原显示时间 500ms
onCompleted 手势绘制完成回调

使用示例

Step1:在项目pubspec.yaml添加依赖

dependencies:
    flutter_gesture_unlock: ^1.0.6

Step2 初始化控件

GestureUnlockView(
        size: LcfarmSize.dp(331), //设置大点,让触摸区域变大。让触摸更有效。
        padding: LcfarmSize.dp(40),
        roundSpace: LcfarmSize.dp(40),
        defaultColor: LcfarmColor.colorE3E4E6,
        selectedColor: LcfarmColor.color3776E9,
        failedColor: LcfarmColor.colorFF5656,
        disableColor: LcfarmColor.color30E3E4E6,
        solidRadiusRatio: 0.3,
        lineWidth: LcfarmSize.dp(2),
        touchRadiusRatio: 0.3,
        onCompleted: _gestureComplete,
      );
      
      
 void _gestureComplete(List selected, UnlockStatus status) async {
    switch (_notifier.status) {
      case GestureStatus.create:
      case GestureStatus.createFailed:
        if (selected.length < 4) {
          _notifier.setStatus(
            status: GestureStatus.createFailed,
            gestureTxt: "连接数不能小于4个,请重新设置",
          );
          _gestureUnlockView.updateStatus(UnlockStatus.failed);
        } else {
          _notifier.setStatus(
            status: GestureStatus.verify,
            gestureTxt: "请再次绘制解锁密码",
            resetGestureTxt: "点击此处以重新开始",
          );
          _gesturePassword = GestureUnlockView.selectedToString(selected);
          _gestureUnlockView.updateStatus(UnlockStatus.success);
          _indicator.setSelectPoint(selected);
        }
        break;
      case GestureStatus.verify:
      case GestureStatus.verifyFailed:
        String password = GestureUnlockView.selectedToString(selected);
        if (_gesturePassword == password) {
          showTips("手势密码设置成功");
          //保存密码
    
        } else {
          _notifier.setStatus(
            status: GestureStatus.verifyFailed,
            gestureTxt: "与上一次绘制不一致, 请重新绘制",
          );
          _gestureUnlockView.updateStatus(UnlockStatus.failed);
        }
        break;
      case GestureStatus.verifyFailedCountOverflow:
        break;
    }
  }

指纹

由于官方插件库已经提供有 local_auth 库,在这里就不大赘述,具体使用就参考Flutter官方local_auth插件库。

最后

  如果在使用过程遇到问题,欢迎下方留言交流。

  Pub 库地址

学习资料

  • Flutter 中文网
  • Flutter Packages
  • Flutter 电子书
  • Flutter 社区中文资源网

请大家不吝点赞!因为您的点赞是对我最大的鼓励,谢谢!

你可能感兴趣的:(Flutter 手势指纹解锁)