android - Flutter FormField Validator 验证失败
问题描述
我尝试通过使用 FormField 包装来创建自定义 TextField。它按我想要的方式工作得很好.. 直到我尝试多次使用它的实例.. 例如,我创建了 InputTextField,所以每当我想多次使用它时,例如全名、电子邮件和电话号码。它会返回错误。但是当我使用它一次或注释掉 InputTextWidget 的 3 个验证器函数中的 2 个时。它会运作良好。
错误消息:在 null 上调用了 getter 'isEmpty'。接收方:null 尝试调用:isEmpty
我的代码片段如下
class InputTextWidget extends StatelessWidget {
final String hintText;
final TextInputType keyboardType;
final TextInputAction keyboardAction;
final TextEditingController inputController;
final double height;
final FormFieldValidator<String> validator;
const InputTextWidget(
{Key key,
@required this.hintText,
@required this.keyboardType,
@required this.keyboardAction,
@required this.inputController,
this.validator,
this.height = 50})
: super(key: key);
@override
Widget build(BuildContext context) {
return FormField(
validator: validator,
builder: (FormFieldState formFieldState) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: height,
width: double.maxFinite,
decoration: BoxDecoration(
border: Border.all(
color: AppColors.inputBorderColor,
),
borderRadius: BorderRadius.all(
Radius.circular(8),
),
),
child: TextFormField(
// Notify the FormField State of Changes
onChanged: (String value) {
formFieldState.didChange(value);
},
controller: inputController,
style: TextStyle(fontSize: 14),
keyboardType: keyboardType,
textInputAction: keyboardAction,
decoration:
InputDecoration.collapsed(hintText: hintText).copyWith(
hasFloatingPlaceholder: false,
contentPadding: EdgeInsets.symmetric(
vertical: 15,
horizontal: 10,
),
),
),
),
// Show Form Field Error
_showError(formFieldState),
],
);
});
}
Widget _showError(FormFieldState formFieldState) {
if (formFieldState.hasError)
return Padding(
padding: EdgeInsets.only(left: 8.0, top: 5),
child: Text(
formFieldState.errorText,
style: TextStyle(
color: AppColors.errorColor,
fontWeight: FontWeight.w500,
fontSize: 10,
),
),
);
return SizedBox();
}
}
我在表单中使用自定义验证器的地方。
Form(
autovalidate: true,
key: formKey,
child: Column(
children: [
InputTextWidget(
hintText: "full Name",
keyboardType: TextInputType.text,
keyboardAction: null,
inputController: _fullName,
validator: (value) {
if (value.isEmpty) return "Full Name field is required";
return null;
},
),
SizedBox(height: 20),
InputTextWidget(
hintText: "Email Address",
keyboardType: TextInputType.emailAddress,
keyboardAction: null,
inputController: _email,
validator: (String value) {
if (value.isEmpty) return "Email field is required";
if (!FormValidator.isValidateEmail(value))
return "Invalid email address";
return null;
},
),
SizedBox(height: 20),
InputTextWidget(
hintText: "Phone Number",
keyboardType: TextInputType.phone,
keyboardAction: null,
inputController: _phoneNumber,
validator: (String value) {
if (value.isEmpty)
return "Phone Number field is required";
if (!FormValidator.isValidPhoneNumber(value))
return "Invalid Phone Number";
return null;
},
),
],
),
),
解决方案
validator
你在小部件构建时执行的FormField
,一个小技巧将是使用该validator
属性来TextFormField
代替。
以您的代码为例添加了一个演示:
class InputTextWidget extends StatelessWidget {
final String hintText;
final TextInputType keyboardType;
final TextInputAction keyboardAction;
final TextEditingController inputController;
final double height;
final FormFieldValidator<String> validator;
const InputTextWidget(
{Key key,
@required this.hintText,
@required this.keyboardType,
@required this.keyboardAction,
@required this.inputController,
this.validator,
this.height = 50})
: super(key: key);
@override
Widget build(BuildContext context) {
return FormField(
builder: (FormFieldState formFieldState) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: height,
width: double.maxFinite,
decoration: BoxDecoration(
border: Border.all(),
borderRadius: BorderRadius.all(
Radius.circular(8),
),
),
child: TextFormField(
// new line
validator: validator, // use validator in [TextFormField]
// Notify the FormField State of Changes
onChanged: (String value) {
formFieldState.didChange(value);
},
controller: inputController,
style: TextStyle(fontSize: 14),
keyboardType: keyboardType,
textInputAction: keyboardAction,
decoration:
InputDecoration.collapsed(hintText: hintText).copyWith(
hasFloatingPlaceholder: false,
contentPadding: EdgeInsets.symmetric(
vertical: 15,
horizontal: 10,
),
),
),
),
// Show Form Field Error
_showError(formFieldState),
],
);
},
);
}
推荐阅读
- html - 简单的横幅广告 - 有没有更好的桌面和移动布局方式?( Flexbox / CSS 网格)
- php - 从多维关联 JSON 中获取特定值
- c++ - 什么时候应该对流使用 fail 函数?
- wordpress - 如何在 xampp 中同时安装 wordpress 和 drupal
- vue.js - Vue 中的数据方法和上下文问题
- combine - ObservedObject 只传递其默认值;不是它的赋值。为什么?
- r - 如何将 huxtable 居中?
- python - 使用 Python 抓取表格
- r - 如何为 R 中的每一行分配数据?
- javascript - 在异步函数中使用 ts-mockito 引发错误