flutter - Flutter:TextFormField的onSaved方法不将值存储到变量中
问题描述
我有一个表单,提示用户输入地址。该表单被分解为多个 TextFormField 小部件,这些小部件在一个名为address_widget.dart
. 这些小部件是从文件中调用的:AddressPage.dart
. 表单加载并得到正确验证,但 onSaved 方法保存的值没有address_widget.dart
存储在变量city
和address
. AddressPage.dart
打印变量city
and时address
,将打印 null。这是正确的方法还是我错过了什么?
address_widget.dart
Widget buildCity(city) {
return TextFormField(
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 2 * SizeConfig.textMultiplier,
),
decoration: InputDecoration(
labelText: 'City',
),
validator: (String value) {
if (value.isEmpty) {
return 'This field is Required';
}
},
onSaved: (String value) {
city = value;
},
);
}
Widget buildAddress(address) {
return TextFormField(
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 2 * SizeConfig.textMultiplier,
),
decoration: InputDecoration(
labelText: 'Address',
),
validator: (String value) {
if (value.isEmpty) {
return 'This field is Required';
}
},
onSaved: (String value) {
address = value;
},
);
}
地址页面.dart
import 'package:userproject/widgets/address_widget.dart';
class AddressPage extends StatefulWidget {
@override
_AddressPageState createState() => _AddressPageState();
}
class _AddressPageState extends State<AddressPage> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
String city;
String address;
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: Form(
key: _formKey,
child: Column(
children: <Widget>[
Text(
'Enter your Address',
style: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
),
buildCity(city),
buildAddress(address),
Row(
children: [
RaisedButton(
onPressed: () {
if (!_formKey.currentState.validate()) {
return;
}
_formKey.currentState.save();
print("city - $city"); // prints null
print("address- $address"); // prints null
},
),
],
)
],
),
),
),
}
}
代码已被简化以便于参考。
解决方案
您必须使用 aTextEditingController
从文本字段中获取数据。
class _AddressWidgetState extends State<AddressWidgetScreen> {
final myController = TextEditingController();
//a string to store the input from the text field
String city = '';
@override
void dispose() {
// Clean up the controller when the widget is disposed.
myController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Row(
children: [
//in your case TextFormField
TextField(
controller: myController,
),
RaisedButton(
onPressed: () {
//store the data from textfield to our new string
city = myController.text.toString();
//therest of your logic
},
textColor: Colors.white,),
奖金提示
此外,作为一种好的做法,您应该在运行时使用ValueObjects来验证不同类中的表单
推荐阅读
- c - 自定义 Shell Seg 错误
- html - 为什么我的阵列只在视图中更新一次?
- css - 在css中设置宽度100%后调整高度
- c++ - 从重载函数初始化 std::function 对象
- python - 如何解决在 Powershell Prompt 中运行 TabPy 时出现权限错误的问题
- php - Laravel eloquent 从不一定有关系的表关系中将数据从大到小排序
- arrays - 如何在 mongoDB 的文档数组中更新我的对象
- python - Heroku + Celery - 拒绝连接
- sql - 使用带有聚合计数的连接的 SQL 选择查询
- git - git clone 失败,“--stdin 需要一个致命的 git 存储库:fetch-pack:invalid index-pack output”