如何在Flutter中将验证器传递给“ TextFormField”?

时间:2019-04-06 11:47:32

标签: android ios dart flutter

我正在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

6 个答案:

答案 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),