Flutter表单验证插件ready_validation的使用
Flutter表单验证插件ready_validation的使用
如何使用
如果你在使用本地化,必须在你的MaterialApp中添加localizationDelegate
return MaterialApp(
localizationsDelegates: [
ReadyValidationMessages.delegate,
...其他委托
],
home: MyApplicationHome(),
);
如果你想在整个应用中使用指定的消息,可以这样做
ValidationMessagesConfig(
messages: ReadyValidationMessagesAr(),
child: // 屏幕或MaterialApp
);
不用担心,每个验证都有一个自定义消息的参数。
使用方法
/// 非常简单
TextFormField(
validator: context
.string()
.required()
.notEmpty()
.hasMaxLength(10)
.hasMinLength(15)
.isNumber()
.greaterThan(10),
);
解释
- 它获取
String?值的验证器。 - 它检查值是否不为null,并将验证器转换为
String而不是String?。此时我们可以使用非空字符串验证。
- 检查字符串是否为空。
- 检查字符串的最大长度。
- 检查字符串的最小长度。
- 检查字符串是否为数字,并且如果通过则将验证器转换为
num验证器。此时我们可以使用所有数字验证,如
greaterThan。 - 检查转换后的数字是否大于10。
- 如果任何验证失败,它将返回其验证消息,并不会继续进行后续验证。
非上下文验证
BuildContext用于应用本地化和全局配置的本地化,但有时你需要检查是否有效。这同样得到了支持,这次你不需要验证是否需要,因为值已经是非空的。
var number = "7";
var isValid = number
.validateWith((v) => v.isNumber())
.validateWith((v) => v.isBetween(5, 10))
.isValid();
/// 或者
isValid = number.validateWith((v) => v.isNumber().isBetween(5, 10)).isValid();
// 忽略:避免打印
print(isValid);
可用验证
所有类型
requirednotEqualequalisInisNotInvalidateWith
字符串
isEmailisCreditCardstartsWithcontainsendsWithnotEmptynotEmptyOrWhiteSpacematcheshasLengthhasMinLengthhasMaxLengthhasRangeisAngelCompanyisAngelJobisCrunchbaseOrganizationisCrunchbasePersonisFacebookUrlisGitHubUrlisGooglePlusUrlisHackerNewsUserUrlisHackerNewsItemUrlisInstagramUrlisLinkedInProfileisLinkedInCompanyisLinkedInPostisRedditUrlisSnapchatUrlisStackexchangeUrlisStackoverflowQuestionUrlisStackoverflowUserUrlisTelegramProfileUrlisMediumPostUrlisMediumUserUrlisTwitterStatusUrlisTwitterUserUrlisYoutubeChannelUrlisYoutubeVideoUrlisYoutubeUserUrl
数字
lessThangreaterThanisBetweenlessThanOrEqualgreaterThanOrEqualisBetweenOrEqualisDivisibleByisNegativeisPositiveisEvenisOdd
日期
isAfterisAfterOrEqualisBeforeisBeforeOrEqualisBetweenisBetweenOrEqual
注意:大多数验证器都有带有前缀
Fn的替代品,例如startsWithFn,它接受函数而不是值。
验证器
/// 字符串验证器
context.string();
/// 数字验证器
context.number();
/// 整数验证器
context.integer();
/// 小数验证器
context.decimal(); // 对于双精度浮点数
/// 布尔验证器
context.boolean();
/// 日期时间验证器
context.dateTime();
/// 时间选择器验证器(即将添加)
context.timeOfDay();
/// 列表验证器
context.list<T>();
/// 映射验证器
context.map<K,V>();
/// 其他验证器
context.validator<T>();
转换
在任何步骤中,你可以将验证器转换为另一种类型,它仍然可以在字段中使用。
假设我们创建了一个验证器,用于我们的TextFormField,它接受一个字符串类型的验证器。
因此,我们的验证器将是:
context.string();
现在我们需要将其转换为数字验证器。
context
.string()
.required() // 确保它不为null
.transform((v) => int.parse(v))
现在你可以使用任何数字验证,如greaterThan,但你不能使用hasMaxLength,因为它对于字符串而言,直到你再次将其转换为字符串验证器。
条件验证
context
.string()
.required()
.hasMaxLength(10)
.hasMinLength(15)
.when((x) => false) /// 在这一点上`hasMinLength`被忽略
.isNumber()
.greaterThan(10),
/// 所以验证顺序将是
/// `required` => `hasMaxLength` => `isNumber` => `greaterThan`
高级
有时候你想要使用自己的消息,那么你必须创建自己的委托和类。
默认委托看起来像这样:
class _ReadyValidationMessagesDelegate
extends LocalizationsDelegate<ReadyValidationMessages> {
const _ReadyValidationMessagesDelegate();
[@override](/user/override)
Future<ReadyValidationMessages> load(Locale locale) {
return SynchronousFuture<ReadyValidationMessages>(
lookupReadyValidationMessages(locale));
}
[@override](/user/override)
bool isSupported(Locale locale) =>
<String>['ar', 'en', 'fr', 'ur'].contains(locale.languageCode);
[@override](/user/override)
bool shouldReload(_ReadyValidationMessagesDelegate old) => false;
}
ReadyValidationMessages lookupReadyValidationMessages(Locale locale) {
// 当仅指定了语言代码时的查找逻辑。
switch (locale.languageCode) {
case 'ar':
return ReadyValidationMessagesAr();
case 'en':
return ReadyValidationMessagesEn();
case 'fr':
return ReadyValidationMessagesFr();
case 'ur':
return ReadyValidationMessagesUr();
}
throw FlutterError(
'ReadyValidationMessages.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.');
}
你也需要创建你自己的ReadyValidationMessages类。
现在,不要使用我们的委托,而是使用你自己的。
return MaterialApp(
localizationsDelegates: [
CustomReadyValidationMessages(),
...其他委托
],
home: MyApplicationHome(),
);
注入
如果你需要制作自己的验证器,它可以与其他验证器一起使用,比如这样:
TextFormField(
validator: context
.string()
.required()
.myCustomValidation() /// 这是你自定义的验证
.hasMaxLength(10)
.hasMinLength(15)
.isNumber()
.greaterThan(10),
);
为此,你必须扩展字段验证器。
extension MyCustomValidationExtension<T> on FieldValidator<T, String> {
FieldValidator<T, String> myCustomValidation() {
return next(
(messages, value) => !validate(value) /// 在这里验证文本
? "My custom message"
: null,
);
}
}
/// FieldValidator 接受两个泛型参数
/// 第一个是调用者,意味着传递给验证器的值的类型是什么
/// 因为我们需要验证器与字符串值一起工作,并且任何转换为字符串的类型,我们将使用T作为第一个参数
完整示例Demo
import 'package:flutter/material.dart';
import 'package:ready_validation/ready_validation.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Ready Validation Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
[@override](/user/override)
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _formKey = GlobalKey<FormState>();
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Ready Validation Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
decoration: InputDecoration(labelText: 'Enter Number'),
validator: context
.string()
.required()
.isNumber()
.greaterThan(0),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Form is valid!')),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Form is invalid!')),
);
}
},
child: Text('Submit'),
),
],
),
),
),
);
}
}
更多关于Flutter表单验证插件ready_validation的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter表单验证插件ready_validation的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用 ready_validation 插件进行 Flutter 表单验证的示例代码。ready_validation 是一个用于 Flutter 的表单验证库,可以简化表单字段的验证过程。
首先,确保你已经在 pubspec.yaml 文件中添加了 ready_validation 依赖:
dependencies:
flutter:
sdk: flutter
ready_validation: ^x.y.z # 请替换为最新版本号
然后运行 flutter pub get 来安装依赖。
接下来是一个完整的示例代码,展示了如何使用 ready_validation 进行表单验证:
import 'package:flutter/material.dart';
import 'package:ready_validation/ready_validation.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _formKey = GlobalKey<FormState>();
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
late ReadyValidation _readyValidation;
@override
void initState() {
super.initState();
_readyValidation = ReadyValidation()
..addValidator('email', _emailController, [
RequiredValidator(errorText: 'Email is required'),
EmailValidator(errorText: 'Email is not valid'),
])
..addValidator('password', _passwordController, [
RequiredValidator(errorText: 'Password is required'),
MinLengthValidator(6, errorText: 'Password must be at least 6 characters long'),
]);
}
@override
void dispose() {
_emailController.dispose();
_passwordController.dispose();
super.dispose();
}
void _submitForm() {
if (_formKey.currentState!.validate()) {
if (_readyValidation.validate()) {
// 表单验证通过,执行提交逻辑
print('Form submitted successfully');
} else {
// 使用ready_validation验证失败,显示错误信息
_readyValidation.showErrors(context);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Form Validation Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
TextFormField(
controller: _emailController,
decoration: InputDecoration(labelText: 'Email'),
validator: (value) {
// 这里的validator可以留空,因为ready_validation会处理
return null;
},
),
TextFormField(
controller: _passwordController,
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
validator: (value) {
// 这里的validator可以留空,因为ready_validation会处理
return null;
},
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _submitForm,
child: Text('Submit'),
),
],
),
),
),
);
}
}
在这个示例中:
- 我们在
initState方法中初始化了ReadyValidation对象,并为email和password字段添加了相应的验证规则。 TextFormField的validator属性留空,因为我们使用ready_validation来处理验证逻辑。- 在
_submitForm方法中,首先使用 Flutter 自带的FormState.validate方法进行初步验证(通常用于非空验证),然后使用ReadyValidation.validate方法进行更复杂的验证。 - 如果
ReadyValidation.validate返回false,则调用ReadyValidation.showErrors方法显示错误信息。
这个示例展示了如何使用 ready_validation 插件进行表单验证,同时结合了 Flutter 自带的表单验证机制。

