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);
可用验证
所有类型
required
notEqual
equal
isIn
isNotIn
validateWith
字符串
isEmail
isCreditCard
startsWith
contains
endsWith
notEmpty
notEmptyOrWhiteSpace
matches
hasLength
hasMinLength
hasMaxLength
hasRange
isAngelCompany
isAngelJob
isCrunchbaseOrganization
isCrunchbasePerson
isFacebookUrl
isGitHubUrl
isGooglePlusUrl
isHackerNewsUserUrl
isHackerNewsItemUrl
isInstagramUrl
isLinkedInProfile
isLinkedInCompany
isLinkedInPost
isRedditUrl
isSnapchatUrl
isStackexchangeUrl
isStackoverflowQuestionUrl
isStackoverflowUserUrl
isTelegramProfileUrl
isMediumPostUrl
isMediumUserUrl
isTwitterStatusUrl
isTwitterUserUrl
isYoutubeChannelUrl
isYoutubeVideoUrl
isYoutubeUserUrl
数字
lessThan
greaterThan
isBetween
lessThanOrEqual
greaterThanOrEqual
isBetweenOrEqual
isDivisibleBy
isNegative
isPositive
isEven
isOdd
日期
isAfter
isAfterOrEqual
isBefore
isBeforeOrEqual
isBetween
isBetweenOrEqual
注意:大多数验证器都有带有前缀
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 自带的表单验证机制。