android - Flutter - 为什么 formKey.currentState.reset 实际上并没有清除字段?
问题描述
我想要做的是在取消表单提交后清除条目。我正在尝试使用_formKey.currentState.reset()但这些字段没有被清理。我应该有一种逐场清洁的方法吗?下面我将使用用户名和权重字段显示我的代码,但我决定不放入代码中的其他字段(DropdownButton 和 Radio)以免太长:
class UserDetailForm extends StatefulWidget {
final User user;
const UserDetailForm(this.user);
@override
_UserDetailFormState createState() => _UserDetailFormState();
}
class _UserDetailFormState extends State<UserDetailForm> {
final UserController controller = UserController();
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: Form(
key: _formKey,
autovalidate: true,
child: Column(
children: <Widget>[
TextFormField(
initialValue: widget.user.name,
decoration: const InputDecoration(labelText: 'Name *'),
validator: (value) {
if (value.isEmpty) {
return 'Insert your name';
}
return null;
},
onChanged: (value) {
setState(() => widget.user.name = value);
}),
TextFormField(
initialValue: widget.user.weight,
decoration: const InputDecoration(
labelText: 'Weight',
),
onChanged: (value) {
setState(() => widget.user.weight = value);
}),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
MaterialButton(
child: Text("Cancel"),
onPressed: () {
_formKey.currentState.reset(); //NOT WORKING, SHOULD CLEAN THE FORM
Navigator.of(context).pop();
},
),
MaterialButton(
child: Text("Save"),
onPressed: () async {
if (_formKey.currentState.validate()) {
controller.updateUser(widget.user);
Navigator.of(context).pop();
}
},
),
],
),
],
),
),
),
);
}
}
#Edit 1 - 使用TextEditingController(仅用于重量)问题仍然存在,取消表单提交后的条目没有被清理
class UserDetailForm extends StatefulWidget {
final User user;
const UserDetailForm(this.user);
@override
_UserDetailFormState createState() => _UserDetailFormState();
}
class _UserDetailFormState extends State<UserDetailForm> {
final UserController controller = UserController();
final _formKey = GlobalKey<FormState>();
TextEditingController weightController;
initState() {
weightController = TextEditingController(text: widget.user.weight);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: Form(
key: _formKey,
autovalidate: true,
child: Column(
children: <Widget>[
TextFormField(
initialValue: widget.user.name,
decoration: const InputDecoration(labelText: 'Name *'),
validator: (value) {
if (value.isEmpty) {
return 'Insert your name';
}
return null;
},
onChanged: (value) {
setState(() => widget.user.name = value);
}),
TextFormField(
controller: weightController,
decoration: const InputDecoration(
labelText: 'Weight',
),
onChanged: (value) {
setState(() => widget.user.weight = value);
}),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
MaterialButton(
child: Text("Cancel"),
onPressed: () {
_formKey.currentState.reset();
weightController.text = "";
Navigator.of(context).pop();
},
),
MaterialButton(
child: Text("Save"),
onPressed: () async {
if (_formKey.currentState.validate()) {
controller.updateUser(widget.user);
Navigator.of(context).pop();
}
},
),
],
),
],
),
),
),
);
}
}
解决方案
_formKey.currentState.reset()
将作为此 Form 的后代的每个 FormField 重置为其FormField.initialValue
,这就是您的代码中发生的事情。单击取消时,初始值仍在屏幕中。要解决这个问题,您需要使用TextEditingController
. 所以首先初始化控制器:
TextEditingController weightController = TextEditingController(text: "test");
TextEditingController nameController = TextEditingController(text: "test1");
并给每个控制器一个初始值(例如:测试)。然后绑定每个controller
:field
TextFormField(
controller : emailController,
decoration: const InputDecoration(labelText: 'Name *'),
validator: (value) {
if (value.isEmpty) {
return 'Insert your name';
}
return null;
}),
TextFormField(
controller: nameController,
decoration: const InputDecoration(
labelText: 'Weight',
)),
删除该initialValue
属性,因为您在创建控制器时已经在初始化该字段。最后下onPressed()
:
onPressed: () {
_formKey.currentState.reset();
nameController.text = "";
emailController.text = "";
},
将初始测试的值更改为空string
。
推荐阅读
- sql - 左外连接 SQL 到 LINQ 扩展方法
- javascript - IE 不加载 css 类 - 用 sass 编译(scss 文件)
- firebase - 在 android 设备中打开时,发布 apk 已立即关闭(Recat -native)
- matlab - 基本类型变量的处理程序
- sql - Oracle 分层路径作为单独的行
- php - 如何将GD中创建的图像添加到模板
- php - 代码 - UC SEG STATUS NOT ALLOWED 当我尝试使用创建乘客姓名记录 API 预订飞行航段时发生 Sabre 错误?
- database - 在 Oracle 模式上创建触发器以替换某些字符
- apache-spark - 如何在多个 RDD 上使用 groupByKey()?
- c# - decimal.Round 的奇怪行为