我正在Flutter应用程序中为表单动态生成文本字段。请检查以下代码
Widget _buildInputFields(
String label,
TextEditingController textController,
TextInputType textInputType,
IconData icon,
Color iconColor,
) {
return Container(
margin: EdgeInsets.only(left: 20, bottom: 20),
child: Container(
padding: EdgeInsets.only(right: 20),
child: Row(
children: <Widget>[
Flexible(
child: TextFormField(
controller: textController,
validator: (value) {
if (value.isEmpty) {
return 'Please enter some text';
}
},
style: new TextStyle(color: Colors.white),
keyboardType: textInputType,
decoration: InputDecoration(
labelText: label,
fillColor: Colors.white,
labelStyle: TextStyle(
color: Colors.white, fontWeight: FontWeight.w600),
enabledBorder: OutlineInputBorder(
borderSide:
const BorderSide(color: Colors.white30, width: 2.0),
borderRadius: BorderRadius.circular(25.0),
),
suffixIcon: IconButton(
icon: Icon(icon, color: iconColor),
onPressed: () {},
)),
),
),
],
),
));
}
上面的方法以我需要的样式返回一个TextFormField
,因此我不必将其重新编码数百次。我只要调用该方法,就会得到一个新的TextFormField
无论如何,我需要进行表单验证,并且每个字段都有不同的验证。在Flutter中,如何将validator
传递给textformfield
?
答案 0 :(得分:1)
由于您已经在使用验证器,我想您只需要将其作为参数传递到_buildInputFields
中,对吧?
会是这样的:
Widget _buildInputFields(
...
Color iconColor,
Function validator,
) {
...
child: TextFormField(
controller: textController,
validator: validator,
style: new TextStyle(color: Colors.white),
...
}
您可以使用它,您会很好的。
但是,您甚至可以更加具体,并使用验证器Function
类型,如下所示:
Widget _buildInputFields(
...
Color iconColor,
FormFieldValidator<String> validator,
...
因此,您可以将验证器定义为State
类的方法,然后在_buildInputFields
调用中重复使用它们,或直接指定它们。
在下面的示例中,您有一个名称字段,它使用_notEmptyValidator(在同一类中定义的方法)。由于LastName遵循相同的逻辑,因此将重用此方法。
...
String _notEmptyValidator(String value) {
if (value.isEmpty) {
return 'Please enter some text';
}
}
...
Column(
children: <Widget>[
_buildInputFields("Name", _notEmptyValidator),
_buildInputFields("Last Name", _notEmptyValidator),
text" : null),
]
...
在下面的示例中,我保留了以前的字段,但是添加了一个新字段。这个新字段具有非常具体的验证逻辑,我将在_buildInputFields
调用中定义验证方法,因此不会在其他字段中重用它。
...
Column(
children: <Widget>[
_buildInputFields("Name", _notEmptyValidator),
_buildInputFields("Last Name", _notEmptyValidator),
text" : null),
_buildInputFields("Valid Number", (value) {
if (double.tryParse(value) == null) {
return "Please input a valid number";
}
},
]
...
答案 1 :(得分:1)
您可以简单地将验证器作为参数传递,就像您对其他参数所做的一样。您需要做的就是传递一个将String作为参数并返回String的函数。
//username validator possible structure
Function(String) usernameValidator = (String username){
if(username.isEmpty){
return 'Username empty';
}else if(username.length < 3){
return 'Username short';
}
return null;
};
//password validator possible structure
passwordValidator(String password){
if(password.isEmpty){
return 'Password empty';
}else if(password.length < 3){
return 'PasswordShort';
}
return null;
}
//new build function
Widget _buildInputFields(
String label,
TextEditingController textController,
TextInputType textInputType,
IconData icon,
Color iconColor,
String Function(String) validator
) {
return Container(
margin: EdgeInsets.only(left: 20, bottom: 20),
child: Container(
padding: EdgeInsets.only(right: 20),
child: Row(
children: <Widget>[
Flexible(
child: TextFormField(
controller: textController,
validator: validator,
style: new TextStyle(color: Colors.white),
keyboardType: textInputType,
decoration: InputDecoration(
labelText: label,
fillColor: Colors.white,
labelStyle: TextStyle(
color: Colors.white, fontWeight: FontWeight.w600),
enabledBorder: OutlineInputBorder(
borderSide:
const BorderSide(color: Colors.white30, width: 2.0),
borderRadius: BorderRadius.circular(25.0),
),
suffixIcon: IconButton(
icon: Icon(icon, color: iconColor),
onPressed: () {},
)),
),
),
],
),
));
}
//calling your function
_buildInputFields(label, textController, textInputType, icon, iconColor, usernameValidator);
_buildInputFields(label, textController, textInputType, icon, iconColor, passwordValidator);
答案 2 :(得分:0)
如果您需要向方法发送的不仅仅是值,您还可以在验证器中创建一个内部函数。 我需要它来在验证器中实现内部化。
TextFormField(
// The validator receives the text that the user has entered.
validator: (value) {
return myMethod(value, context, ...);
},
//... other attributes
)
答案 3 :(得分:0)
对于 Flutter 2
Custom Widget Function
CupertinoTextFormFieldRow customTextField(
String pretext, String supportText, Function(String) validatorFun) {
return CupertinoTextFormFieldRow(
prefix: Text(pretext),
placeholder: supportText,
validator: (val) => validatorFun(val!),
);
}
Define validator functions
acceptNonNull(String value) {
if (value.trim().isEmpty) {
return 'Please enter a value';
}
return null;
}
checkPassword(String value) {
if (value.isEmpty) {
return 'Password empty';
} else if (value.length < 8) {
return 'Password too weak';
} //accept only if string contains both alphabests and numerics
else if (!value.contains(RegExp(r'^[a-zA-Z0-9]+$'))) {
return 'Password should contain aplpha numeric characters';
}
return null;
}
Build your Widgets
customTextField("First Name", "Enter Your First Name Here",acceptNonNull),
customTextField("Last Name", "Enter Your Last Name Here", acceptNonNull),
customTextField("Password", "Choose a Password", checkPassword)
答案 4 :(得分:0)
只是一个简单的例子,使用nullsafety、flutter 2、getx
登录_屏幕
validator: (value) {
return AuthController.instance.emailValidator(AuthController.instance.emailController.text);
},
Auth_Controller
emailValidator(String email){
if ((!email.contains('@')) ||
(email.trim().length < 8))
{
return 'Invalid email';
}
//validado com sucesso
return null;
}
答案 5 :(得分:0)
nonybrighto 答案完全正确,但添加空检查后更新的代码是
// Function to create form field
Widget createFormField(String label, TextEditingController controller,
String? Function(String?)? validator) {
return TextFormField(
decoration: InputDecoration(labelText: label),
controller: controller,
autovalidate: true,
validator: validator,
);
}
// Validator
String? Function(String?)? idValidator = (String? value) {
if (value!.isEmpty) {
return 'Id Must be entered';
} else {
return int.tryParse(value) == null ? 'Id Must be number' : null;
}
};
// Finally
createFormField('Id', idController, idValidator),