0

我有一个TextFormField使用验证器检查输入是否满足一组要求的方法。如果输入不满足特定要求,则红色的错误文本将相应地通知用户。如果密码满足所有要求,我想返回绿色文本(“安全密码”)。

class RegForm extends StatefulWidget {
  const RegForm({Key? key}) : super(key: key);

  @override
  _RegFormState createState() => _RegFormState();
}

class _RegFormState extends State<RegForm> {
  Color errorClr = Colors.red;
  final String checkAll =
                r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#\$&*~]).{8,}$';
  final String checkLetters = r'^(?=.*?[A-Z])(?=.*?[a-z])';
  final String checkNumbers = r'^(?=.*?[0-9])';
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: TextFormField(
        autovalidateMode: AutovalidateMode.onUserInteraction,
        validator: (value) {
          if (value == null || value.isEmpty) {
            return 'Please enter a valid password';
          } else {
            if (value.length < 8)
              return 'Password has to be 8 characters or more!';
            else if (!RegExp(checkLetters).hasMatch(value))
              return 'Password has to contain Uppercase and Lowercase letters!';
            else if (!RegExp(checkNumbers).hasMatch(value))
              return 'Password has to contain numbers!';
            else if (RegExp(checkAll).hasMatch(value)) {
              errorClr = Colors.green;
              return 'Very secure password!';
            }
          }
          errorClr = Colors.green;
          return 'Secure password!';
        },
        decoration: InputDecoration(
          errorStyle: TextStyle(
            color: errorClr,
          ),
          contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
          hintText:
              'Password must be at least 8 characters long, contains numbers and both upper and lowercase letters',
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(10.0),
          ),
        ),
      ),
    );
  }
}

上面的代码不会以绿色返回“安全密码”文本,我认为它是因为验证器不会重建小部件,因此errorStyle不会更新。有没有办法使这项工作?

4

1 回答 1

0

您不能setState()从验证器函数中调用,这是更改errorClr成功文本所需的。验证器函数也需要返回null以指示验证通过;所以你不能简单地返回安全密码!.

你觉得用什么helperText来输出成功信息。

如果非空,则文本显示在 InputDecorator.child 下方,与 errorText 位于同一位置。如果指定了非空 errorText 值,则不显示帮助文本。

定义一个指示密码是否有效的新变量(默认值:false):

bool validPassword = false;

用于onChanged检查有效密码:

onChanged: (String value) {
  if (RegExp(checkAll).hasMatch(value))
    setState(() {
      validPassword = true;
    });
  },

添加helperTexthelperStyle到您的InputDecoration

 helperText: validPassword ? 'Secure Password' : null,
 helperStyle: TextStyle(color: Colors.green),

完整示例:

class _RegFormState extends State<RegForm> {
  final String checkAll = r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#\$&*~]).{8,}$';
  final String checkSpecial = r'^(?=.*?[!@#\$&*~])';
  final String checkLetters = r'^(?=.*?[A-Z])(?=.*?[a-z])';
  final String checkNumbers = r'^(?=.*?[0-9])';

  bool validPassword = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: TextFormField(
        autovalidateMode: AutovalidateMode.onUserInteraction,
          validator: (value) {
            if (value == null || value.isEmpty || value.trim().length < 8) // use trim() for the whitrespaces
              return 'Password has to be 8 characters or more!';

            if (!RegExp(checkLetters).hasMatch(value))
              return 'Password has to contain Uppercase and Lowercase letters!';

            if (!RegExp(checkNumbers).hasMatch(value))
              return 'Password has to contain numbers!';

            if (!RegExp(checkSpecial).hasMatch(value))
              return 'Password has to contain a special character!';

            return null; // to indicate a success
         },
         onChanged: (String value) {
           if (RegExp(checkAll).hasMatch(value))
             setState(() {
               validPassword = true;
             });
           },
        decoration: InputDecoration(
          contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
          helperText: validPassword ? 'Secure Password' : null,
          helperStyle: TextStyle(color: Colors.green),
          hintText:
          'Password must be at least 8 characters long, contains numbers and both upper and lowercase letters',
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(10.0),
         ),
        ),
      ),
    );
  }
于 2021-06-13T08:18:07.420 回答