如何基于验证器动态更改textformfield中errorstyle的颜色?
How to dynamically change colour of errorstyle in textformfield based on validator?
我有一个 TextFormField
使用验证器检查输入是否满足一组要求。如果输入不满足特定要求,red 中的错误文本将相应地通知用户。如果密码满足所有要求,我想 return green 文本(“安全密码”)。
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),
),
),
),
);
}
}
上面的代码不会 return 绿色的“安全密码”文本,我认为这是因为验证程序不会重建小部件,因此 errorStyle
不会更新。有没有办法让这个工作?
您不能从验证程序函数内部调用 setState()
,这是您需要更改 errorClr
或成功文本的地方。另外验证器函数需要returnnull
来表示验证通过;所以你不能简单地 return 安全密码!.
你觉得用helperText
输出成功信息怎么样
If non-null, the text is displayed below the InputDecorator.child, in the same location as errorText. If a non-null errorText value is specified then the helper text is not shown.
定义一个指示密码是否有效的新变量(默认值:false):
bool validPassword = false;
使用onChanged
检查密码是否有效:
onChanged: (String value) {
if (RegExp(checkAll).hasMatch(value))
setState(() {
validPassword = true;
});
},
将 helperText
和 helperStyle
添加到您的 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),
),
),
),
);
}
我有一个 TextFormField
使用验证器检查输入是否满足一组要求。如果输入不满足特定要求,red 中的错误文本将相应地通知用户。如果密码满足所有要求,我想 return green 文本(“安全密码”)。
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),
),
),
),
);
}
}
上面的代码不会 return 绿色的“安全密码”文本,我认为这是因为验证程序不会重建小部件,因此 errorStyle
不会更新。有没有办法让这个工作?
您不能从验证程序函数内部调用 setState()
,这是您需要更改 errorClr
或成功文本的地方。另外验证器函数需要returnnull
来表示验证通过;所以你不能简单地 return 安全密码!.
你觉得用helperText
输出成功信息怎么样
If non-null, the text is displayed below the InputDecorator.child, in the same location as errorText. If a non-null errorText value is specified then the helper text is not shown.
定义一个指示密码是否有效的新变量(默认值:false):
bool validPassword = false;
使用onChanged
检查密码是否有效:
onChanged: (String value) {
if (RegExp(checkAll).hasMatch(value))
setState(() {
validPassword = true;
});
},
将 helperText
和 helperStyle
添加到您的 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),
),
),
),
);
}