forms - 为什么点击提交时 Flutter 表单会重置所有字段?
问题描述
我有一个FORM
withe 32TEXTFORMFIELDS
和一个按钮来验证和导航到输出屏幕。
TextButton(
onPressed: () {
_formKey.currentState.save(); // I added this line which does nothing
if (_formKey.currentState.validate()) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return OutputScreen();
},
),
);
} else {
_showAlert(context); // third partypackage alert function
}
},
child: Text(
'Calculate',
),
),
我的问题是,如果用户单击提交,有时它会重置所有字段,无论验证是真还是假;
这是我经过大量测试后发现的一个东西,当用户输入一个文本字段时,输入键盘有一个“DONE”键,用户可以使用它来结束编辑。现在,如果用户没有使用它并且只是点击下一个字段进行输入并继续单击我创建的 subit 按钮,它会重置所有表单。
有任何想法吗?或者有没有办法强制用户在完成输入后点击键盘上的“完成”。
提前致谢。
///////////////////////////////////////// / 编辑:完整代码示例 ///////////////////////////////////// ///////
class CementInputPage extends StatefulWidget {
@override
_CementInputPageState createState() => _CementInputPageState();
}
class _CementInputPageState extends State<CementInputPage> {
static const double sizedBoxHeight = 8;
final _formKeyCement = GlobalKey<FormState>();
CementData cementData = new CementData();
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFDDDDDD),
appBar: AppBar(
title: Text("Cement Input Data"),
),
body: SafeArea(
child: Form(
key: _formKeyCement,
child: ListView(
children: [
// Header data
WhiteBoxContainer( //container I created in another file
boxTitle: 'Header',
childWidget: Column(
children: [
//TODO: Validate date format
myStringTextInputRow('Date'),
SizedBox(height: sizedBoxHeight),
myStringTextInputRow('Operator Company'),
SizedBox(height: sizedBoxHeight),
myStringTextInputRow('Cement Contractor'),
SizedBox(height: sizedBoxHeight),
myStringTextInputRow('Well Name'),
SizedBox(height: sizedBoxHeight),
myStringTextInputRow('Field Name'),
SizedBox(height: sizedBoxHeight),
myStringTextInputRow('Rig'),
SizedBox(height: sizedBoxHeight),
myStringTextInputRow('Rig Supervisor'),
SizedBox(height: sizedBoxHeight),
myStringTextInputRow('Cement Supervisor'),
SizedBox(height: sizedBoxHeight),
],
),
),
//
//Well data
WhiteBoxContainer(
boxTitle: 'Well Data',
childWidget: Column(
children: [
Row(
children: [
Expanded(
child: TextFormField(
keyboardType:
TextInputType.numberWithOptions(decimal: true),
autovalidateMode:
AutovalidateMode.onUserInteraction,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: "Section Depth (ft)",
),
validator: (value) {
return sectionTDValidator(value);
},
),
),
checkInputStatus(InputValidationStatus.notValid),
],
),
SizedBox(height: sizedBoxHeight),
Row(
children: [
Expanded(
child: TextFormField(
keyboardType:
TextInputType.numberWithOptions(decimal: true),
autovalidateMode:
AutovalidateMode.onUserInteraction,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: "Casing length (ft)",
),
validator: (value) {
return casingLengthValidator(value);
},
),
),
checkInputStatus(InputValidationStatus.notValid),
],
),
Container(
child: TextButton(
onPressed: () {
_formKeyCement.currentState.save(); // line I added which did nothing
if (_formKeyCement.currentState.validate()) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return CementOutputScreen();
},
),
);
} else {
//I want to show an alert dialog
child: Text(
'Calculate',
),
),
),
],
),
),
),
);
}
String sectionTDValidator(String value) {
if (value.isNotEmpty) {
cementData.sectionTD = double.parse(value);
if (cementData.sectionTD < kMinWellDepth) {
return 'Section Depth is too short!';
} else if (cementData.sectionTD > kMaxWellDepth) {
return 'Section depth is too long!';
} else if (cementData.casingLength != null &&
cementData.casingLength > cementData.sectionTD) {
return 'Section depth is shorter than casing length!';
}
} else {
cementData.sectionTD = null;
}
return null;
}
String casingLengthValidator(String value) {
if (value.isNotEmpty) {
cementData.casingLength = double.parse(value);
if (cementData.casingLength < kMinWellDepth) {
return 'Casing Length is too short!';
} else if (cementData.casingLength > kMaxWellDepth) {
return 'Casing Length is too long!';
} else if (cementData.sectionTD != null &&
cementData.casingLength > cementData.sectionTD) {
return 'Casing Length is longer than section depth!';
} else if (cementData.leadLength != null) {
if (cementData.leadLength > cementData.casingLength) {
return 'Casing length is shorter than lead length!';
} else if (cementData.tailLength != null) {
// check tail length
if (cementData.tailLength > cementData.casingLength) {
return 'Casing length is shorter than lead length!';
} else if ((cementData.leadLength + cementData.tailLength) >
cementData.casingLength) {
return 'Casing length is shorter than total cement length!';
}
}
} else if (cementData.shoeTrackLength != null &&
cementData.shoeTrackLength >= cementData.casingLength) {
return 'Shoe track length is >= casing length!';
}
} else {
cementData.casingLength = null;
}
return null;
}
String shoeTrackLengthValidator(String value) {
if (value.isNotEmpty) {
cementData.shoeTrackLength = double.parse(value);
if (cementData.casingLength != null &&
cementData.shoeTrackLength >= cementData.casingLength) {
return 'Shoe track length is >= casing length!';
}
} else {
cementData.shoeTrackLength = null;
}
return null;
}
String stickUpLengthValidator(String value) {
if (value.isNotEmpty) {
cementData.stickUpLength = double.parse(value);
if (cementData.stickUpLength > kMaxStickUpLength) {
return 'Stick up length is too long!';
}
} else {
cementData.stickUpLength = null;
}
return null;
}
}
Row myStringTextInputRow(String labelText) {
return Row(
children: [
Expanded(
child: TextFormField(
keyboardType: TextInputType.name,
maxLines: 2,
minLines: 1,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: labelText,
),
),
),
checkInputStatus(InputValidationStatus.notCritical),
],
);
}
Container checkInputStatus(InputValidationStatus inputStatus) {
if (inputStatus == InputValidationStatus.notValid) {
return Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 3),
child: Icon(
Icons.clear,
color: Colors.red[900],
size: 18.0,
semanticLabel: 'Feedback icon',
),
);
} else if (inputStatus == InputValidationStatus.valid) {
return Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 3),
child: Icon(
Icons.done,
color: Colors.green[900],
size: 18.0,
semanticLabel: 'Feedback icon',
),
);
} else {
return Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 3),
child: Icon(
Icons.flaky,
color: Colors.orange[700],
size: 18.0,
semanticLabel: 'Feedback icon',
),
);
}
;
}
解决方案
尝试添加TextEditingController
到您TextFormField
的 s 并删除autovalidateMode
.
推荐阅读
- react-navigation - createBrowserApp 不适用于 react-navigation v5
- ios - TensorflowLite iOS Swift
- javascript - 我想使用innerHTML在屏幕上显示一个计数器,但即使我使用睡眠功能,它也不能循环工作?
- excel - 基于字符串标识符计算列表级别 - 多级列表
- python-3.x - 如何用 sympy 计算两个多边形的交集面积?
- java - 为什么 parseBoolean 不抛出异常?
- java - while循环减少另一个类中的实例变量
- python - 不让我下载 pip,说有权限问题,我需要更新 pip
- javascript - React - list.push 不是一个函数
- git - 致命:不是 git 存储库(或任何父目录):.git on rake task on Heroku