Flutter登录功能优化插件flutter_login_fix的使用
Flutter 登录功能优化插件 flutter_login_fix 的使用
flutter_login 是一个现成的登录/注册小部件,具有许多动画效果来展示 Flutter 的能力。
安装
请按照以下步骤安装 flutter_login:
dependencies:
flutter_login:
参考文档
属性表
| 属性名 | 类型 | 描述 |
|---|---|---|
| onSignup | AuthCallback |
当用户在注册模式下点击提交按钮时调用。接收一个包含用户名、密码及任何其他字段的 SignupData 对象。 |
| onConfirmSignup | ConfirmSignupCallback |
当用户点击确认注册时调用。如果未指定,则注册不会被用户确认。 |
| confirmSignupRequired | ConfirmSignupRequiredCallback |
动态决定是否需要确认。如果未指定,且 onConfirmSignup 指定,则会由用户确认。 |
| confirmSignupKeyboardType | TextInputType |
确认注册字段的键盘类型。 |
| onResendCode | AuthCallback |
当用户点击重新发送代码按钮时调用。仅在提供了 onConfirmSignup 时才需要。 |
| onLogin | AuthCallback |
当用户在登录模式下点击提交按钮时调用。 |
| onRecoverPassword | RecoverCallback |
当用户点击提交按钮进行密码恢复时调用。 |
| onConfirmRecover | ConfirmRecoverCallback |
当用户在密码恢复模式下提交确认码并设置新密码时调用。如果未指定,将不使用确认码来恢复密码。 |
| title | String |
登录屏幕上方的大文本,通常为应用或公司名称。留空或为 null 则无标题。 |
| logo | ImageProvider 或 String |
用于显示的 logo 图像的图像提供者或资源路径字符串。 |
| messages | LoginMessages |
描述所有标签、文本提示、按钮文本和其他身份验证描述。 |
| theme | LoginTheme |
FlutterLogin 的主题。如果没有指定,将使用默认主题,并使用最近的 Theme 小部件的颜色方案。 |
| userType | LoginUserType |
FlutterLogin 的用户类型。如果没有指定,默认使用电子邮件作为用户类型。 |
| userValidator | FormFieldValidator<String> |
用户字段验证逻辑。在此添加自定义验证。默认为电子邮件验证逻辑。期望返回一个错误消息字符串(显示)或 null(验证成功)。 |
| validateUserImmediately | bool |
是否在失去焦点后验证电子邮件(true)或在表单提交后验证(false)。默认为 false。 |
| passwordValidator | FormFieldValidator<String> |
与 userValidator 类似,但针对密码。 |
| onSubmitAnimationCompleted | Function |
在提交动画完成后调用。在此放置路由过渡逻辑。 |
| logoTag | String |
Hero 标签用于 logo 图像。如果没有指定,它将在更改路由时淡出。 |
| titleTag | String |
Hero 标签用于标题文本。如果想要不同的字体大小在英雄动画之前和之后,请指定 LoginTheme.beforeHeroFontSize 和 LoginTheme.afterHeroFontSize。 |
| showDebugButtons | bool |
显示调试按钮以快速前进/后退登录动画。在发布模式下,此值将被覆盖为 false 无论传入的值是什么。 |
| hideForgotPasswordButton | bool |
如果设置为 true,则隐藏忘记密码按钮。 |
| hideProvidersTitle | bool |
如果设置为 true,则隐藏登录提供者上方的标题。如果提供者列表为空,则此选项无效,因为标题将被隐藏。默认为 false。 |
| disableCustomPageTransformer | bool |
禁用可能导致 RenderBox was not laid out 错误的自定义过渡。更多信息请参见 #97。 |
| additionalSignUpFields | Map<String, UserFormField> |
用于指定额外的表单字段;表单在注册后立即显示。最多可以提供 6 个额外字段。 |
| onSwitchToAdditionalFields | AdditionalFieldsCallback |
当用户切换到附加字段时调用。 |
| navigateBackAfterRecovery | bool |
成功恢复密码后导航回登录页面。 |
| savedEmail | String |
预填的用户字段值(即通过其他方式从以前的会话中保存的值,例如通过 SharedPreferences)。 |
| savedPassword | String |
预填的密码字段值(即通过其他方式从以前的会话中保存的值,例如通过 SharedPreferences)。 也会设置 Auth 类中的确认密码。 |
| termsOfService | TermOfService |
注册期间列出的一系列服务条款。在 onSignup 回调 LoginData 中包含一个 TermOfServiceResult 列表。 |
| children | [Widget] |
可以添加到登录屏幕堆栈中的小部件列表。可以用来显示自定义横幅或徽标。 |
| scrollable | bool |
设置为 true 时,登录卡片变为可滚动而不是根据需要调整大小。 |
| headerWidget | Widget |
可以放置在登录卡片顶部的小部件。 |
示例代码
基本示例
import 'package:flutter/material.dart';
import 'package:flutter_login/flutter_login.dart';
import 'dashboard_screen.dart';
const users = const {
'dribbble@gmail.com': '12345',
'hunter@gmail.com': 'hunter',
};
class LoginScreen extends StatelessWidget {
Duration get loginTime => Duration(milliseconds: 2250);
Future<String?> _authUser(LoginData data) {
debugPrint('Name: ${data.name}, Password: ${data.password}');
return Future.delayed(loginTime).then((_) {
if (!users.containsKey(data.name)) {
return 'User not exists';
}
if (users[data.name] != data.password) {
return 'Password does not match';
}
return null;
});
}
Future<String?> _signupUser(SignupData data) {
debugPrint('Signup Name: ${data.name}, Password: ${data.password}');
return Future.delayed(loginTime).then((_) {
return null;
});
}
Future<String> _recoverPassword(String name) {
debugPrint('Name: $name');
return Future.delayed(loginTime).then((_) {
if (!users.containsKey(name)) {
return 'User not exists';
}
return null;
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return FlutterLogin(
title: 'ECORP',
logo: AssetImage('assets/images/ecorp-lightblue.png'),
onLogin: _authUser,
onSignup: _signupUser,
onSubmitAnimationCompleted: () {
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => DashboardScreen(),
));
},
onRecoverPassword: _recoverPassword,
);
}
}
带有登录提供者的示例
import 'package:flutter/material.dart';
import 'package:flutter_login/flutter_login.dart';
import 'dashboard_screen.dart';
const users = const {
'dribbble@gmail.com': '12345',
'hunter@gmail.com': 'hunter',
};
class LoginScreen extends StatelessWidget {
Duration get loginTime => Duration(milliseconds: 2250);
Future<String?> _authUser(LoginData data) {
debugPrint('Name: ${data.name}, Password: ${data.password}');
return Future.delayed(loginTime).then((_) {
if (!users.containsKey(data.name)) {
return 'User not exists';
}
if (users[data.name] != data.password) {
return 'Password does not match';
}
return null;
});
}
Future<String?> _signupUser(SignupData data) {
debugPrint('Signup Name: ${data.name}, Password: ${data.password}');
return Future.delayed(loginTime).then((_) {
return null;
});
}
Future<String> _recoverPassword(String name) {
debugPrint('Name: $name');
return Future.delayed(loginTime).then((_) {
if (!users.containsKey(name)) {
return 'User not exists';
}
return null;
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return FlutterLogin(
title: 'ECORP',
logo: AssetImage('assets/images/ecorp-lightblue.png'),
onLogin: _authUser,
onSignup: _signupUser,
loginProviders: [
LoginProvider(
icon: FontAwesomeIcons.google,
label: 'Google',
callback: () async {
debugPrint('start google sign in');
await Future.delayed(loginTime);
debugPrint('stop google sign in');
return null;
},
),
LoginProvider(
icon: FontAwesomeIcons.facebookF,
label: 'Facebook',
callback: () async {
debugPrint('start facebook sign in');
await Future.delayed(loginTime);
debugPrint('stop facebook sign in');
return null;
},
),
LoginProvider(
icon: FontAwesomeIcons.linkedinIn,
callback: () async {
debugPrint('start linkdin sign in');
await Future.delayed(loginTime);
debugPrint('stop linkdin sign in');
return null;
},
),
LoginProvider(
icon: FontAwesomeIcons.githubAlt,
callback: () async {
debugPrint('start github sign in');
await Future.delayed(loginTime);
debugPrint('stop github sign in');
return null;
},
),
],
onSubmitAnimationCompleted: () {
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => DashboardScreen(),
));
},
onRecoverPassword: _recoverPassword,
);
}
}
使用 ThemeData 进行主题定制
import 'package:flutter/material.dart';
import 'package:flutter_login/flutter_login.dart';
import 'dashboard_screen.dart';
class LoginScreen extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return FlutterLogin(
title: 'ECORP',
logo: AssetImage('assets/images/ecorp.png'),
onLogin: (_) => Future(null),
onSignup: (_) => Future(null),
onSubmitAnimationCompleted: () {
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => DashboardScreen(),
));
},
onRecoverPassword: (_) => Future(null),
);
}
}
自定义标签
import 'package:flutter/material.dart';
import 'package:flutter_login/flutter_login.dart';
import 'dashboard_screen.dart';
class LoginScreen extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return FlutterLogin(
title: 'ECORP',
logo: AssetImage('assets/images/ecorp.png'),
onLogin: (_) => Future(null),
onSignup: (_) => Future(null),
onSubmitAnimationCompleted: () {
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => DashboardScreen(),
));
},
onRecoverPassword: (_) => Future(null),
messages: LoginMessages(
userHint: 'User',
passwordHint: 'Pass',
confirmPasswordHint: 'Confirm',
loginButton: 'LOG IN',
signupButton: 'REGISTER',
forgotPasswordButton: 'Forgot huh?',
recoverPasswordButton: 'HELP ME',
goBackButton: 'GO BACK',
confirmPasswordError: 'Not match!',
recoverPasswordDescription:
'Lorem Ipsum is simply dummy text of the printing and typesetting industry',
recoverPasswordSuccess: 'Password rescued successfully',
),
);
}
}
主题定制
import 'package:flutter/material.dart';
import 'package:flutter_login/flutter_login.dart';
import 'dashboard_screen.dart';
class LoginScreen extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
final inputBorder = BorderRadius.vertical(
bottom: Radius.circular(10.0),
top: Radius.circular(20.0),
);
return FlutterLogin(
title: 'ECORP',
logo: AssetImage('assets/images/ecorp-lightgreen.png'),
onLogin: (_) => Future(null),
onSignup: (_) => Future(null),
onSubmitAnimationCompleted: () {
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => DashboardScreen(),
));
},
onRecoverPassword: (_) => Future(null),
theme: LoginTheme(
primaryColor: Colors.teal,
accentColor: Colors.yellow,
errorColor: Colors.deepOrange,
titleStyle: TextStyle(
color: Colors.greenAccent,
fontFamily: 'Quicksand',
letterSpacing: 4,
),
bodyStyle: TextStyle(
fontStyle: FontStyle.italic,
decoration: TextDecoration.underline,
),
textFieldStyle: TextStyle(
color: Colors.orange,
shadows: [Shadow(color: Colors.yellow, blurRadius: 2)],
),
buttonStyle: TextStyle(
fontWeight: FontWeight.w800,
color: Colors.yellow,
),
cardTheme: CardTheme(
color: Colors.yellow.shade100,
elevation: 5,
margin: EdgeInsets.only(top: 15),
shape: ContinuousRectangleBorder(
borderRadius: BorderRadius.circular(100.0)),
),
inputTheme: InputDecorationTheme(
filled: true,
fillColor: Colors.purple.withOpacity(.1),
contentPadding: EdgeInsets.zero,
errorStyle: TextStyle(
backgroundColor: Colors.orange,
color: Colors.white,
),
labelStyle: TextStyle(fontSize: 12),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.blue.shade700, width: 4),
borderRadius: inputBorder,
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.blue.shade400, width: 5),
borderRadius: inputBorder,
),
errorBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.red.shade700, width: 7),
borderRadius: inputBorder,
),
focusedErrorBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.red.shade400, width: 8),
borderRadius: inputBorder,
),
disabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 5),
borderRadius: inputBorder,
),
),
buttonTheme: LoginButtonTheme(
splashColor: Colors.purple,
backgroundColor: Colors.pinkAccent,
highlightColor: Colors.lightGreen,
elevation: 9.0,
highlightElevation: 6.0,
shape: BeveledRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
);
}
}
更多关于Flutter登录功能优化插件flutter_login_fix的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter登录功能优化插件flutter_login_fix的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,flutter_login_fix 并不是一个广泛认知的 Flutter 插件,但基于你的要求,我将假设这是一个假想的插件,旨在优化 Flutter 应用中的登录功能。在实际开发中,优化登录功能可能涉及表单验证、错误处理、用户体验增强等多个方面。
以下是一个使用 Flutter 和一些常见插件(如 form_field_validator 用于表单验证)来实现优化登录功能的示例代码。虽然这不是直接使用 flutter_login_fix,但它展示了如何实现类似的优化效果。
1. 添加依赖
首先,在 pubspec.yaml 文件中添加必要的依赖:
dependencies:
flutter:
sdk: flutter
provider: ^6.0.0
form_field_validator: ^2.0.0
2. 创建登录表单
接下来,创建一个登录表单,包括用户名和密码字段,以及登录按钮。使用 form_field_validator 进行表单验证。
import 'package:flutter/material.dart';
import 'package:form_field_validator/form_field_validator.dart';
import 'package:provider/provider.dart';
class LoginScreen extends StatefulWidget {
@override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final _formKey = GlobalKey<FormState>();
String _email = '';
String _password = '';
String _errorMessage = '';
void _submit() {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
// 在这里添加登录逻辑,比如调用API
_performLogin();
}
}
Future<void> _performLogin() async {
// 模拟API调用
await Future.delayed(Duration(seconds: 2));
// 假设验证成功
setState(() {
_errorMessage = '';
// 这里可以导航到主屏幕或其他页面
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('登录'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(labelText: '邮箱'),
validator: MultiValidator([
RequiredValidator(errorText: '邮箱是必填项'),
EmailValidator(errorText: '请输入有效的邮箱地址'),
]),
onSaved: (value) {
_email = value!;
},
),
TextFormField(
decoration: InputDecoration(labelText: '密码'),
validator: MultiValidator([
RequiredValidator(errorText: '密码是必填项'),
MinLengthValidator(6, errorText: '密码长度不能少于6个字符'),
]),
obscureText: true,
onSaved: (value) {
_password = value!;
},
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _submit,
child: Text('登录'),
),
SizedBox(height: 10),
Text(
_errorMessage,
style: TextStyle(color: Colors.red),
),
],
),
),
),
);
}
}
3. 使用 Provider 管理状态(可选)
如果需要在应用的不同部分共享登录状态(例如用户信息),可以使用 provider 包来管理状态。
class UserProvider with ChangeNotifier {
User? _user;
User? get user => _user;
void logIn(String email, String password) {
// 在这里添加实际的登录逻辑,比如调用API
// 假设验证成功,设置用户信息
_user = User(email: email, password: password); // 注意:不要在实际应用中存储密码
notifyListeners();
}
void logOut() {
_user = null;
notifyListeners();
}
}
class User {
final String email;
final String password; // 仅用于示例,实际中不应存储密码
User({required this.email, required this.password});
}
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => UserProvider()),
],
child: MyApp(),
),
);
}
在 MyApp 中,你可以根据用户登录状态来显示不同的界面,比如登录页面或主屏幕。
总结
虽然我们没有直接使用 flutter_login_fix 插件,但上面的代码展示了如何使用 Flutter 和一些常见插件来实现一个优化过的登录功能,包括表单验证、错误处理和状态管理。这些都是优化登录体验的关键要素。如果你有一个具体的 flutter_login_fix 插件,并且需要更具体的帮助,请提供更多关于该插件的信息。

