前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter 密码锁定屏幕

Flutter 密码锁定屏幕

作者头像
老孟Flutter
发布2021-06-09 10:39:56
4.8K0
发布2021-06-09 10:39:56
举报
文章被收录于专栏:FlutterFlutter

Flutter 让我对高效构建令人愉悦的UI很感兴趣,而且它允许您同时为两个平台创建。直到最近一年,我一直使用touchID和FaceID作为身份验证工具。在任何情况下,如最新的Andriod先决条件所指出的那样,您需要在生物识别认证被破坏或受损的偶然机会上提供选择性的认证策略。

在在本文中,我们将探讨「Flutter中」「密码锁定屏幕」。我们将看到如何在flutter应用程序中使用「passcode_screen」软件包来实现演示程序密码锁定屏幕。

pub 地址:https://pub.dev/packages/passcode_screen

密码锁定屏幕

一个与阶段无关的Flutter软件包,用于显示密码输入屏幕,例如Native iOS。屏幕可适应颜色,大小,文本样式等。它将显示在flutter应用程序中使用密码屏幕时如何解锁屏幕。

该演示视频演示了如何在Flutter中创建密码锁定屏幕。它显示了如何在flutter应用程序中使用「passcode_screen」软件包来运行密码锁定屏幕。它显示密码输入屏幕以解锁屏幕。它会显示在您的设备上。

使用

添加依赖

代码语言:javascript
复制
passcode_screen: ^1.2.2+1

引入

代码语言:javascript
复制
import 'package:passcode_screen/passcode_screen.dart';

运行命令:「flutter packages get」

启用「AndriodX」

代码语言:javascript
复制
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true

在libs目录下创建 「demo_page.dart」 文件

代码语言:javascript
复制
Center(
  child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      Text('You are ${isAuthenticated ? '' : 'not'}'
          ' authenticated',style: TextStyle(fontSize: 16),),
      SizedBox(height: 10,),
      _lockScreenButton(context),
    ],
  ),
),

在主屏幕上,我们将添加文本“You are not authenticated”,这意味着用户可以解锁密码屏幕,然后更改身份验证文本。否则,您的设备上将显示未通过身份验证。我们将添加一个**_lockScreenButton(context)。**

代码语言:javascript
复制
_lockScreenButton(BuildContext context) => MaterialButton(
  padding: EdgeInsets.only(left: 50,right: 50),
  color: Theme.of(context).primaryColor,
  child: Text('Lock Screen',style: TextStyle(color: Colors.white,
      fontWeight: FontWeight.bold,fontSize: 17),),
  onPressed: () {
    _showLockScreen(
      context,
      opaque: false,
      cancelButton: Text(
        'Cancel',
        style: const TextStyle(fontSize: 16, color: Colors.white,),
        semanticsLabel: 'Cancel',
      ),
    );
  },
);

在**_lockScreenButton()中**,我们将使用按钮。我们将在按钮内添加填充,颜色,文本和onPressed方法,并在此方法上添加**_showLockScreen()**小部件。当我们运行应用程序时,我们应该获得屏幕的输出,如屏幕下方的截图所示。

img

定义**_showLockScreen()**

代码语言:javascript
复制
_showLockScreen(BuildContext context,
    {bool opaque,
      CircleUIConfig circleUIConfig,
      KeyboardUIConfig keyboardUIConfig,
      Widget cancelButton,
      List<String> digits}) {
  Navigator.push(
      context,
      PageRouteBuilder(
        opaque: opaque,
        pageBuilder: (context, animation, secondaryAnimation) => PasscodeScreen(
          title: Text(
            'Enter Passcode',
            textAlign: TextAlign.center,
            style: TextStyle(color: Colors.white, fontSize: 28),
          ),
          circleUIConfig: circleUIConfig,
          keyboardUIConfig: keyboardUIConfig,
          passwordEnteredCallback: _passcodeEntered,
          cancelButton: cancelButton,
          deleteButton: Text(
            'Delete',
            style: const TextStyle(fontSize: 16, color: Colors.white),
            semanticsLabel: 'Delete',
          ),
          shouldTriggerVerification: _verificationNotifier.stream,
          backgroundColor: Colors.black.withOpacity(0.8),
          cancelCallback: _passcodeCancelled,
          digits: digits,
          passwordDigits: 6,
          bottomWidget: _passcodeRestoreButton(),
        ),
      ));
}

在此小部件中,我们将添加「PasscodeScreen()。「在屏幕内部,我们将添加标题,内置的圆圈配置和键盘。我们将添加一个」passwordEnteredCallback」方法。在此方法中,添加_passcodeEntered小部件,我们将在下面进行定义。添加一个cancelButton,deleteButton,shouldTriggerVerification,cancelCallback,密码数字和bottomWidget。

代码语言:javascript
复制
final StreamController<bool> _verificationNotifier = StreamController<bool>.broadcast();
_passcodeEntered(String enteredPasscode) {
  bool isValid = storedPasscode == enteredPasscode;
  _verificationNotifier.add(isValid);
  if (isValid) {
    setState(() {
      this.isAuthenticated = isValid;
    });
  }
}

密码输入完成回调,并在密码正确与否时通知密码屏幕。用户可以添加任何storedPasscodelike 654321等。如果密码有效,则对屏幕进行身份验证。当我们运行应用程序时,我们应该获得屏幕的输出,如屏幕下方的截图所示。

img

不要忘记关闭流。用户可以处理它。

代码语言:javascript
复制
@override 
void dispose(){_ 
  verificationNotifier.close(); 
  super.dispose(); 
}

定义**_passcodeRestoreButton()**

代码语言:javascript
复制
Align(
  alignment: Alignment.bottomCenter,
  child: Container(
    margin: const EdgeInsets.only(bottom: 10.0, top: 20.0),
    child: FlatButton(
      child: Text(
        "Reset passcode",
        textAlign: TextAlign.center,
        style: const TextStyle(fontSize: 16, color: Colors.white, fontWeight: FontWeight.w300),
      ),
      splashColor: Colors.white.withOpacity(0.4),
      highlightColor: Colors.white.withOpacity(0.2),
      onPressed: _resetApplicationPassword,
    ),
  ),
);

在此小部件中,如果结果等于结果,则导航pop。否则,使用**_restoreDialog()**小部件,然后弹出。

代码语言:javascript
复制
_restoreDialog(VoidCallback onAccepted) {
  showDialog(
    context: context,
    builder: (BuildContext context) {
      return AlertDialog(
        backgroundColor: Colors.teal[50],
        title: Text(
          "Reset passcode",
          style: const TextStyle(color: Colors.black87),
        ),
        content: Text(
          "Passcode reset is a non-secure operation!\nAre you sure want to reset?",
          style: const TextStyle(color: Colors.black87),
        ),
        actions: <Widget>[
          // usually buttons at the bottom of the dialog
          FlatButton(
            child: Text(
              "Cancel",
              style: const TextStyle(fontSize: 18),
            ),
            onPressed: () {
              Navigator.maybePop(context);
            },
          ),
          FlatButton(
            child: Text(
              "I proceed",
              style: const TextStyle(fontSize: 18),
            ),
            onPressed: onAccepted,
          ),
        ],
      );
    },
  );
}

完整代码:

代码语言:javascript
复制
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_passcode_lock_screen/constant.dart';
import 'package:passcode_screen/circle.dart';
import 'package:passcode_screen/keyboard.dart';
import 'package:passcode_screen/passcode_screen.dart';

class DemoPage extends StatefulWidget {

  @override
  State<StatefulWidget> createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> {
  final StreamController<bool> _verificationNotifier = StreamController<bool>.broadcast();
  bool isAuthenticated = false;

  @override
  void dispose() {
    _verificationNotifier.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blueGrey[100],
      appBar: AppBar(
        automaticallyImplyLeading: false,
        title: Text('Passcode Lock Screen Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('You are ${isAuthenticated ? '' : 'not'}'
                ' authenticated',style: TextStyle(fontSize: 16),),
            SizedBox(height: 10,),
            _lockScreenButton(context),
          ],
        ),
      ),
    );
  }

  _lockScreenButton(BuildContext context) => MaterialButton(
    padding: EdgeInsets.only(left: 50,right: 50),
    color: Theme.of(context).primaryColor,
    child: Text('Lock Screen',style: TextStyle(color: Colors.white,
        fontWeight: FontWeight.bold,fontSize: 17),),
    onPressed: () {
      _showLockScreen(
        context,
        opaque: false,
        cancelButton: Text(
          'Cancel',
          style: const TextStyle(fontSize: 16, color: Colors.white,),
          semanticsLabel: 'Cancel',
        ),
      );
    },
  );


  _showLockScreen(BuildContext context,
      {bool opaque,
        CircleUIConfig circleUIConfig,
        KeyboardUIConfig keyboardUIConfig,
        Widget cancelButton,
        List<String> digits}) {
    Navigator.push(
        context,
        PageRouteBuilder(
          opaque: opaque,
          pageBuilder: (context, animation, secondaryAnimation) => PasscodeScreen(
            title: Text(
              'Enter Passcode',
              textAlign: TextAlign.center,
              style: TextStyle(color: Colors.white, fontSize: 28),
            ),
            circleUIConfig: circleUIConfig,
            keyboardUIConfig: keyboardUIConfig,
            passwordEnteredCallback: _passcodeEntered,
            cancelButton: cancelButton,
            deleteButton: Text(
              'Delete',
              style: const TextStyle(fontSize: 16, color: Colors.white),
              semanticsLabel: 'Delete',
            ),
            shouldTriggerVerification: _verificationNotifier.stream,
            backgroundColor: Colors.black.withOpacity(0.8),
            cancelCallback: _passcodeCancelled,
            digits: digits,
            passwordDigits: 6,
            bottomWidget: _passcodeRestoreButton(),
          ),
        ));
  }

  _passcodeEntered(String enteredPasscode) {
    bool isValid = storedPasscode == enteredPasscode;
    _verificationNotifier.add(isValid);
    if (isValid) {
      setState(() {
        this.isAuthenticated = isValid;
      });
    }
  }

  _passcodeCancelled() {
    Navigator.maybePop(context);
  }

  _passcodeRestoreButton() => Align(
    alignment: Alignment.bottomCenter,
    child: Container(
      margin: const EdgeInsets.only(bottom: 10.0, top: 20.0),
      child: FlatButton(
        child: Text(
          "Reset passcode",
          textAlign: TextAlign.center,
          style: const TextStyle(fontSize: 16, color: Colors.white, fontWeight: FontWeight.w300),
        ),
        splashColor: Colors.white.withOpacity(0.4),
        highlightColor: Colors.white.withOpacity(0.2),
        onPressed: _resetApplicationPassword,
      ),
    ),
  );

  _resetApplicationPassword() {
    Navigator.maybePop(context).then((result) {
      if (!result) {
        return;
      }
      _restoreDialog(() {
        Navigator.maybePop(context);
      });
    });
  }

  _restoreDialog(VoidCallback onAccepted) {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          backgroundColor: Colors.teal[50],
          title: Text(
            "Reset passcode",
            style: const TextStyle(color: Colors.black87),
          ),
          content: Text(
            "Passcode reset is a non-secure operation!\nAre you sure want to reset?",
            style: const TextStyle(color: Colors.black87),
          ),
          actions: <Widget>[
            // usually buttons at the bottom of the dialog
            FlatButton(
              child: Text(
                "Cancel",
                style: const TextStyle(fontSize: 18),
              ),
              onPressed: () {
                Navigator.maybePop(context);
              },
            ),
            FlatButton(
              child: Text(
                "I proceed",
                style: const TextStyle(fontSize: 18),
              ),
              onPressed: onAccepted,
            ),
          ],
        );
      },
    );
  }

}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-05-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老孟Flutter 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 密码锁定屏幕
  • 使用
相关产品与服务
多因子身份认证
多因子身份认证(Multi-factor Authentication Service,MFAS)的目的是建立一个多层次的防御体系,通过结合两种或三种认证因子(基于记忆的/基于持有物的/基于生物特征的认证因子)验证访问者的身份,使系统或资源更加安全。攻击者即使破解单一因子(如口令、人脸),应用的安全依然可以得到保障。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档