org.gradle.jvmargs=-Xmx1536M
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)。**
_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()**小部件。当我们运行应用程序时,我们应该获得屏幕的输出,如屏幕下方的截图所示。
_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。
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等。如果密码有效,则对屏幕进行身份验证。当我们运行应用程序时,我们应该获得屏幕的输出,如屏幕下方的截图所示。
@override void dispose(){_ verificationNotifier.close(); super.dispose(); }定义**_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, ), ), );
_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, ), ], ); }, ); }
完整代码:
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, ), ], ); }, ); } }