欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Flutter實現(xiàn)手勢密碼加密與解鎖功能

 更新時間:2022年04月28日 08:40:21   作者:老李code  
這篇文章主要介紹了如何利用Flutter實現(xiàn)手勢密碼的加密與解鎖,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

前言

密碼的由來:在公元前405年,由古希臘和斯巴達(dá)的戰(zhàn)爭中,由于斯巴達(dá)盟友波斯帝國背叛,導(dǎo)致古希臘和斯巴達(dá)兩敗俱傷,這時斯巴達(dá)抓了一個波斯國的信使,這個信使 沒有任何情報,只有一條有著雜亂無章的希臘字母的普通腰帶,最終斯巴達(dá)統(tǒng)帥破解了這條腰帶,成功擊敗了希臘。這就是世界上最早的密碼。同時也是世界上最早的解密。

密碼在我們生活中無處不在,作為個人隱私的最后一道防線顯得無比的重要,現(xiàn)在世界有各種各樣形形色色的密碼,解密方式也是層出不窮,加密,解密的過程里充滿了數(shù)學(xué)以及計算機的知識,而現(xiàn)在手機的加密的方式也有很多、數(shù)字、手勢、指紋、人臉、虹膜等等方式多種多樣,有加密就有解密、有破譯等等,有些App為了安全起見,例如招商銀行的銀行類的App在每次啟動的時候都需要解鎖驗證身份,那么今天我們用Flutter實現(xiàn)一個其中的加密方式,手勢密碼。

知識點:手勢識別、繪制、動畫

1、繪制靜態(tài)圖形

手勢密碼一般都是九宮格的形狀,所以第一步我們先把這個輔助矩形九宮格畫出來,然后在每一個格子內(nèi)就可以繪制我們喜歡的圖形了,九宮格那就很簡單了。
首先我們定義一個正方形300*300 為九宮格的區(qū)域,然后對這個正方形平均分成9個小格子,我們需要找到這9個小格子的中心點來繪制九宮格,那么我們找到之后把每個小格子的中心用一個List存儲起來方便以后繪制。

代碼:

double size = 300;// 正方形邊長
List<Offset> centerOffset = <Offset>[];// 九宮格中心點

// 上面3個
centerOffset.add(Offset(-size / 3, -size / 3));
centerOffset.add(Offset(-size / 3 + size / 3, -size / 3));
centerOffset.add(Offset(-size / 3 + size / 3 * 2, -size / 3));

// 中間3個
centerOffset.add(Offset(-size / 3, 0));
centerOffset.add(Offset(-size / 3 + size / 3, 0));
centerOffset.add(Offset(-size / 3 + size / 3 * 2, 0));

// 下面3個
centerOffset.add(Offset(-size / 3, size / 3));
centerOffset.add(Offset(-size / 3 + size / 3, size / 3));
centerOffset.add(Offset(-size / 3 + size / 3 * 2, size / 3));

接下來我們就可以用這些點繪制九宮格了。

核心代碼:

Paint paint = Paint()
  ..style = PaintingStyle.stroke
  ..strokeWidth = 2
  ..color = Colors.black87;

canvas.drawRect(
    Rect.fromCenter(center: Offset.zero, width: 300, height: 300), paint);

// 繪制輔助區(qū)域
_drawHelpRect(canvas, size, paint);
void _drawHelpRect(Canvas canvas, Size size, Paint paint) {
  for (int i = 0; i < centerOffset.length; i++) {
    canvas.drawRect(
        Rect.fromCenter(center: centerOffset[i], width: 100, height: 100),
        paint);
  }
}

效果圖:

得到九宮格之后,我們看到很多手勢解鎖小格子內(nèi)都是圓形,這里我們繼續(xù)在每個小格子繪制圓形圖案,

核心代碼:

// 繪制圓
_drawCirCle(canvas, size, paint);
void _drawCirCle(Canvas canvas, Size size, Paint paint) {
 for (int i = 0; i < centerOffset.length; i++) {
   canvas.drawCircle(centerOffset[i], 30, paint..color = Colors.black87);
 }
}

效果圖:

到這里基本圖形已經(jīng)繪制完了。

2、存儲手勢密碼數(shù)據(jù)

首先我們看下手勢解鎖一共有按下、移動、抬起三個動作組成,在移動的過程中會經(jīng)過九宮格內(nèi)部的圓形區(qū)域,也就是說,在經(jīng)過圓形區(qū)域的時候,我們需要將這個數(shù)據(jù)保存下來然后通知畫布進(jìn)行更新,這里的邏輯跟我之前一篇繪制海豚那篇原理一樣,首先創(chuàng)建UnlockController類繼承ChangeNotifier。這里我們將九宮格中的每一個小格子對應(yīng)一個數(shù)字進(jìn)行封裝一下。也是之后的設(shè)置和解鎖需要保存的數(shù)據(jù)。 這樣的話我們上面的九宮格就需要修改一下了,將Offset改為PassWord就行。

數(shù)據(jù)代碼:

class UnlockController extends ChangeNotifier {
  // 存儲按壓的點集合
  List<PassWord> _points = [];

  List<PassWord> get points => _points;

  // 當(dāng)前手指的位置
  Offset? _currentOffset;

  Offset? get currentOffset => _currentOffset;

  //
  set currentOffset(Offset? value) {
    _currentOffset = value;
    notifyListeners();
  }

  addPoint(PassWord offset) {
    _points.add(offset);
    notifyListeners();
  }

  // 清除所有點
  clearAllPoint() {
    _points.clear();
    notifyListeners();
  }
}

class PassWord {
  int num; // 密碼數(shù)字
  Offset offset; // 密碼數(shù)字對應(yīng)的點
  PassWord(this.num, this.offset);
}

有了這些數(shù)據(jù)之后我們接下來就要跟手勢進(jìn)行交互了。

3、添加手勢交互

接著上面剛說的,交互一共有三種狀態(tài),按下、移動、抬起,那么我們就先對這三種狀態(tài)進(jìn)行監(jiān)聽,

GestureDetector(
  child: CustomPaint(
    size: Size(size, size),
    painter:
        _GesturesUnlockPainter(_unlockController, centerOffset),
  ),
  onPanDown: (d) {
    // 手指按下
},
  onPanUpdate: (d) {
    // 移動                
  },
  onPanEnd: (d) {
   // 抬起結(jié)束
  },
)

交互思路: 手勢密碼的特點是每個九宮格只允許點亮一次,再次經(jīng)過不保存數(shù)據(jù)。

按下: 判斷是否在九宮格內(nèi)部任一圓形區(qū)域內(nèi),在:點亮圓形,保存數(shù)據(jù),不在:不做任何操作,

移動: 判斷是否移動到九宮格任一圓形區(qū)域內(nèi),在:判斷是否已點亮-未點亮:點亮圓形,保存數(shù)據(jù),已點亮:不做任何操作,不在區(qū)域內(nèi),也不做數(shù)據(jù)任何操作。

抬起: 獲取密碼,進(jìn)行設(shè)置或驗證。

大概思路還是比較清晰的,下面我們就對這些判斷條件進(jìn)行判斷。

代碼:

///手指按下、移動觸發(fā)
void judgeZone(Offset src) {
  /// 循環(huán)所有的九宮格
  for (int i = 0; i < centerOffset.length; i++) {
    var srcTranslate = src.translate(-size / 2, -size / 2);
    // 判斷手指按的位置是否在九宮格圓形區(qū)域
    if (judgeCircleArea(srcTranslate, centerOffset[i].offset, 30)) {
      // 在 判斷是否已添加
      for (int j = 0; j < _unlockController.points.length; j++) {
        if (_unlockController.points[j] == centerOffset[i]) {
          // 已添加過 返回
          return;
        }
      }
      // 未添加過 進(jìn)行添加
      _unlockController.addPoint(centerOffset[i]);
      return;
    }
  }
  // 無點
}
///判斷出是否在某點的半徑為r圓范圍內(nèi)
bool judgeCircleArea(Offset src, Offset dst, double r)=>(src - dst).distance <= r;

有了手指數(shù)據(jù)之后,我們就能根據(jù)這些數(shù)據(jù)的變化進(jìn)而通知畫布進(jìn)行更新了。

4、繪制、刷新密碼線

上面我們已經(jīng)拿到數(shù)據(jù)了,接下來我們進(jìn)行繪制密碼線,如何刷新畫布之前的文章我已經(jīng)講過很多遍了,這里不熟悉的同學(xué)可以看下之前繪制小海豚那一篇文章貝塞爾曲線繪制一個小海豚,回歸正題,既然我們拿到了手指經(jīng)過的九宮格的中心點,那繪制線就變得非常容易了,

核心代碼:

var offsets = unlockController.points.map((e) => e.offset).toList();
// 繪制按壓點
canvas.drawPoints(
    PointMode.points,
    offsets,
    paint
      ..strokeWidth = 20
      ..strokeCap = StrokeCap.round
      ..color = Colors.red);
// 繪制密碼
Path path = Path();
if (unlockController.points.isNotEmpty) {
  path.moveTo(unlockController.points[0].offset.dx,
      unlockController.points[0].offset.dy);
  if (unlockController.currentOffset != null) {
  // 繪制當(dāng)前手勢線 未經(jīng)過九宮格圓形時
    canvas.drawLine(unlockController.points.last.offset,
        unlockController.currentOffset!, paint..strokeWidth = 2);
  }
}
for (int i = 1; i < unlockController.points.length; i++) {
  path.lineTo(unlockController.points[i].offset.dx,
      unlockController.points[i].offset.dy);
}
canvas.drawPath(path, paint..strokeWidth = 2);

這樣我們就把手勢經(jīng)過的密碼線繪制出來了。

效果圖:

5、加入密碼錯誤動畫

當(dāng)我們輸入密碼錯誤時,給用戶一個提示密碼錯誤的交互也是很有必要的,那么接下來我們就添加一個簡單文字抖動效果提示用戶密碼輸入錯誤。
添加動畫也很簡單,思路: 不斷改變文字的邊距從而達(dá)到抖動效果。

核心代碼:

late AnimationController _animationController =
    AnimationController(vsync: this, duration: Duration(milliseconds: 500));

late CurvedAnimation curvedAnimation =
    CurvedAnimation(curve: Curves.easeIn, parent: _animationController);
late Animation<double> animation =
    Tween(begin: 0.0, end: 10.0).animate(curvedAnimation)
      ..addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          _animationController.reset();
        }
      });
AnimatedBuilder(
    animation: animation,
    builder: (ctx, child) {
      return Container(
        margin: EdgeInsetsDirectional.only(
            bottom: 20,
            start: _errorPwd() * 20,
            end: animation.value),
        child: Text(
          text,
          style: TextStyle(fontSize: 20, color: textColor),
        ),
      );
    }),
    
double _errorPwd() {
  double x = animation.value; // 變化速度 0-10,
  double d = x - x.truncate(); // 獲取這個數(shù)字的小數(shù)部分
  double? y;
  if (d <= 0.5) {
    y = 2 * d;
  } else {
    y = 1 - 2 * (d - 0.5);
  }
  return y;
}

假設(shè)我們設(shè)置的密碼是14789,也就是L型,看下最終效果:

完整源碼之后我會放到github上。

總結(jié)

通過手勢識別我們用到了App中核心的三大框架,手勢、繪制、以及動畫中的知識。其實原理也并不復(fù)雜,只要掌握了這三大框架的核心基礎(chǔ)知識

到此這篇關(guān)于基于Flutter實現(xiàn)手勢密碼加密與解鎖功能的文章就介紹到這了,更多相關(guān)Flutter手勢密碼加密解鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android自定義相機聚焦和顯示框

    Android自定義相機聚焦和顯示框

    這篇文章主要為大家詳細(xì)介紹了Android自定義相機聚焦和顯示框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • android實現(xiàn)倒計時功能代碼

    android實現(xiàn)倒計時功能代碼

    實現(xiàn)倒計時每隔1秒,變換一下時間,截圖如下,感興趣的朋友想看下實現(xiàn)代碼,希望對你學(xué)習(xí)有所幫助
    2013-06-06
  • Android  TimerTask 的簡單應(yīng)用及注意事項

    Android TimerTask 的簡單應(yīng)用及注意事項

    這篇文章主要介紹了Android TimerTask 的簡單應(yīng)用及注意事項的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • android WebView組件使用總結(jié)

    android WebView組件使用總結(jié)

    瀏覽器控件是每個開發(fā)環(huán)境都具備的,這為馬甲神功提供了用武之地,windows的有webbrowser,android和ios都有webview;本篇主要介紹android的webview之強大,感興趣的朋友可以研究下
    2012-12-12
  • 詳解Android 基于TCP和UDP協(xié)議的Socket通信

    詳解Android 基于TCP和UDP協(xié)議的Socket通信

    這篇文章主要介紹了詳解Android 基于TCP和UDP協(xié)議的Socket通信,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • 詳解關(guān)于Android Studio中安裝和gradle的一些坑

    詳解關(guān)于Android Studio中安裝和gradle的一些坑

    本篇文章主要介紹了關(guān)于Android Studio中安裝和gradle的一些坑,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • 快速掌握Android屏幕的知識點

    快速掌握Android屏幕的知識點

    相信不少設(shè)計師和工程師都被安卓設(shè)備紛繁的屏幕搞得暈頭轉(zhuǎn)向,我既做UI設(shè)計,也做過一點安卓界面布局,剛好對這塊內(nèi)容比較熟悉,所以在此我將此部分知識重新梳理出來分享給大家!有需要的朋友們可以參考借鑒,下面來一起學(xué)習(xí)學(xué)習(xí)吧。
    2016-11-11
  • Android 初識 Helloworld 詳解

    Android 初識 Helloworld 詳解

    在Eclipse+ADT中創(chuàng)建HelloWorld非常簡單,直接按照導(dǎo)航下一步就可以了。本文重點不在如何創(chuàng)建,而在理解HelloWorld項目的文件。需要的朋友可以參考下
    2013-07-07
  • android編程之XML文件解析方法詳解(附源碼)

    android編程之XML文件解析方法詳解(附源碼)

    這篇文章主要介紹了android編程之XML文件解析方法,結(jié)合實例形式較為詳細(xì)的分析了Android解析XML文件的sax、pull及Dom三種方法,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-11-11
  • Android開發(fā)之BroadcastReceiver用法實例分析

    Android開發(fā)之BroadcastReceiver用法實例分析

    這篇文章主要介紹了Android開發(fā)之BroadcastReceiver用法,實例分析了Android中廣播的相關(guān)使用技巧,需要的朋友可以參考下
    2015-05-05

最新評論