Flutter:TextFormField Validator 打破了字段的样式
Posted
技术标签:
【中文标题】Flutter:TextFormField Validator 打破了字段的样式【英文标题】:Flutter: TextFormField Validator breaks the style of field 【发布时间】:2020-04-08 17:09:00 【问题描述】:我有这个 TextFormField,我正在努力实现登录/注册屏幕。问题是当验证器将错误弹出到屏幕上时,TextFormField 的边框从圆形边缘变为方形。我该怎么做才能打印出错误?我正在考虑打印整个表单上方或下方的所有内容,但是使用 Valdiator 属性的方法呢? 还是有更有效的方法?
TextFormField 所在的 ListView 似乎在此过程中被破坏,使得在屏幕上打印出验证器后键入非常烦人。
beforeValidator afterValidator
只是 TextFormField:
TextFormField(
validator: (String str) =>
str.isEmpty ? 'Enter a username' : null,
decoration: InputDecoration(
hintText: 'theChadMaster76',
hintStyle: TextStyle(
fontStyle: FontStyle.italic,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.green),
borderRadius: BorderRadius.circular(35.0),
),
focusedBorder: OutlineInputBorder(
//focusBorder changes or not when user first clicks on the field
borderSide: BorderSide(color: Colors.blueAccent),
borderRadius: BorderRadius.circular(35.0),
),
prefixIcon: Icon(Icons
.account_circle), //make the icon also change its color
filled: true,
fillColor: Colors.grey.shade200,
),
textAlign: TextAlign.center,
textAlignVertical: TextAlignVertical.bottom,
onChanged: (String str)
setState(()
userName = str;
);
,
),
整个文件:
class RegistrationScreen extends StatefulWidget
static const String id = 'registration_screen';
@override
_RegistrationScreenState createState() => _RegistrationScreenState();
class _RegistrationScreenState extends State<RegistrationScreen>
final AuthService _auth = AuthService();
final _formKey = GlobalKey<FormState>();
bool loading = false;
String error = '';
String userName = "";
String email = "";
String password = "";
@override
Widget build(BuildContext context)
return loading ? Loading() : Scaffold(
appBar: AppBarModel(),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 30.0),
child: Center(
child: Form(
key: _formKey,
child: ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 50.0),
child: Center(child: Text('add logo')),
),
Padding(
padding: const EdgeInsets.only(left: 20.0, bottom: 10.0),
child: Text(
'Username:',
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w600,
//fontStyle: FontStyle.italic,
),
),
),
TextFormField(
validator: (String str) =>
str.isEmpty ? 'Enter a username' : null,
decoration: InputDecoration(
hintText: 'theChadMaster76',
hintStyle: TextStyle(
fontStyle: FontStyle.italic,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.green),
borderRadius: BorderRadius.circular(35.0),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueAccent),
borderRadius: BorderRadius.circular(35.0),
),
prefixIcon: Icon(Icons
.account_circle), //make the icon also change its color
filled: true,
fillColor: Colors.grey.shade200,
),
textAlign: TextAlign.center,
textAlignVertical: TextAlignVertical.bottom,
onChanged: (String str)
setState(()
userName = str;
);
,
),
SizedBox(height: 30.0),
Padding(
padding: const EdgeInsets.only(left: 20.0, bottom: 10.0),
child: Text(
'Email:',
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w600,
//fontStyle: FontStyle.italic,
),
),
),
TextFormField(
keyboardType: TextInputType.emailAddress,
validator: (String str) =>
str.isEmpty ? 'Enter an email' : null,
decoration: InputDecoration(
hintText: 'bobbyBob@gmail.com',
hintStyle: TextStyle(
fontStyle: FontStyle.italic,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.green),
borderRadius: BorderRadius.circular(35.0),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueAccent),
borderRadius: BorderRadius.circular(35.0),
),
prefixIcon:
Icon(Icons.mail),
filled: true,
fillColor: Colors.grey.shade200,
),
textAlign: TextAlign.center,
textAlignVertical: TextAlignVertical.bottom,
onChanged: (String str)
setState(()
email = str;
);
,
),
SizedBox(height: 30.0),
Padding(
padding: const EdgeInsets.only(left: 20.0, bottom: 10.0),
child: Text(
'Password:',
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w600,
//fontStyle: FontStyle.italic,
),
),
),
TextFormField(
validator: (String str) =>
str.length < 6 ? 'Enter an password 6+ char' : null,
obscureText: true,
decoration: InputDecoration(
hintText: 'secretPassword123!',
hintStyle: TextStyle(
fontStyle: FontStyle.italic,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.green),
borderRadius: BorderRadius.circular(35.0),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueAccent),
borderRadius: BorderRadius.circular(35.0),
),
prefixIcon: Icon(Icons.memory),
filled: true,
fillColor: Colors.grey.shade200,
),
textAlign: TextAlign.center,
textAlignVertical: TextAlignVertical.bottom,
onChanged: (String str)
setState(()
password = str;
);
,
),
SizedBox(
height: 50.0,
),
Center(
child: FlatButton(
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
side: BorderSide(color: Colors.green.shade400),
),
color: Colors.green.shade400,
textColor: Colors.grey.shade300,
padding:
EdgeInsets.symmetric(horizontal: 120.0, vertical: 10.0),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'SUBMIT',
style: TextStyle(
fontSize: 18.0,
letterSpacing: 4.0,
fontStyle: FontStyle.italic,
),
),
),
onPressed: () async
if (_formKey.currentState.validate())
setState(()
loading = true;
);
dynamic result = await _auth.registerWithEmailPassUser(
email, password);
if (result == null)
setState(()
loading = false;
error = "please supply a valid email";
);
,
),
),
],
),
),
),
),
);
【问题讨论】:
【参考方案1】:您只需要覆盖errorBoder 样式,就像您为focusedBorder,enabledBorder 所做的那样。下面是代码sn-p。
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
borderRadius: BorderRadius.circular(35.0),
)
你最终的 TextFormFiled 应该是这样的
TextFormField(
validator: (String str) =>
str.isEmpty ? 'Enter a username' : null,
decoration: InputDecoration(
hintText: 'theChadMaster76',
hintStyle: TextStyle(
fontStyle: FontStyle.italic,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.green),
borderRadius: BorderRadius.circular(35.0),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueAccent),
borderRadius: BorderRadius.circular(35.0),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
borderRadius: BorderRadius.circular(35.0),
),
prefixIcon: Icon(Icons
.account_circle), //make the icon also change its color
filled: true,
fillColor: Colors.grey.shade200,
),
textAlign: TextAlign.center,
textAlignVertical: TextAlignVertical.bottom,
onChanged: (String str)
setState(()
userName = str;
);
,
)
【讨论】:
你可以在这里查看dartpad.dev/1dc24e6c5a38f6d0a914b3620ea0a20b 非常感谢。我还必须添加focusedErrorBorder,现在我明白为什么了。【参考方案2】:您还必须指定 errorBorder 和focusedErrorBorder:
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
borderRadius: BorderRadius.circular(35.0),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
borderRadius: BorderRadius.circular(35.0),
),
请参阅InputDecoration 了解所有可用选项。
【讨论】:
以上是关于Flutter:TextFormField Validator 打破了字段的样式的主要内容,如果未能解决你的问题,请参考以下文章
Flutter - 键盘隐藏时TextFormField变为空白
更改 FLUTTER 中 TextFormField 的默认边框颜色
Flutter 扩展/占用 TextFormField 以填充屏幕的其余部分
Flutter 2 - 设置自动完成 TextFormField 的初始值