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<int> 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 库地址

学习资料

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容