我是新来的颤振,任何帮助将不胜感激。
我在两个不同的屏幕上有两个单独的表格。单击“下一步”按钮验证表单并Navigator.push()
使用第二个表单运行到我的下一个屏幕,之后如果我填写第二个表单的 TextFormFields 并初始化保存然后Navigator.pop()
返回到第一个表单,第一个表单中的数据页面仍然填写,但是一旦我再次运行 Navigator.push() 返回到第二个表单,TextFormFields 是空的。
我的目的是让用户数据在TextFormFields
两个表单中输入后,在不同的屏幕中来回导航。
我尝试initialValue
在 TextFormFields 上使用,但没有奏效。
要导航回来,我正在使用运行后自动创建的后退按钮Navigator.push
这是第一页:
import '../screens/contact_details_screen.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class PersonalDetailsForm extends StatefulWidget {
@override
_PersonalDetailsFormState createState() => _PersonalDetailsFormState();
}
class _PersonalDetailsFormState extends State<PersonalDetailsForm> {
String _title;
String _firstName;
String _middleName;
String _surname;
String _age;
String _gender;
String _dateOfBirth;
DateTime selectedDate = DateTime.now();
TextEditingController _date = new TextEditingController();
final GlobalKey<FormState> _personalDetailsFormKey = GlobalKey<FormState>();
Widget _buildTitle() {
return DropdownButtonFormField(
items: [
DropdownMenuItem<String>(
value: 'Dr',
child: Text('Dr'),
),
DropdownMenuItem<String>(
value: 'Miss',
child: Text('Miss'),
),
DropdownMenuItem<String>(
value: 'Mr',
child: Text('Mr'),
),
DropdownMenuItem<String>(
value: 'Mrs',
child: Text('Mrs'),
),
DropdownMenuItem<String>(
value: 'Ms',
child: Text('Ms'),
),
DropdownMenuItem<String>(
value: 'Prof.',
child: Text('Prof.'),
),
DropdownMenuItem<String>(
value: 'Sir',
child: Text('Sir'),
),
],
validator: (String value) {
if (value == null) {
return 'Title is required';
}
return null;
},
value: _title,
decoration: InputDecoration(labelText: 'Title'),
onChanged: (String value) {
setState(() {
_title = value;
});
},
);
}
Widget _buildFirstName() {
return TextFormField(
decoration: InputDecoration(labelText: 'First Name'),
keyboardType: TextInputType.name,
validator: (String value) {
if (value.isEmpty) {
return 'First name is required';
}
return null;
},
onSaved: (String value) {
_firstName = value;
},
);
}
Widget _buildMiddleName() {
return TextFormField(
decoration: InputDecoration(labelText: 'Middle Name'),
keyboardType: TextInputType.name,
onSaved: (String value) {
_middleName = value;
},
);
}
Widget _buildSurname() {
return TextFormField(
decoration: InputDecoration(labelText: 'Surname Name'),
keyboardType: TextInputType.name,
validator: (String value) {
if (value.isEmpty) {
return 'Surname name is required';
}
return null;
},
onSaved: (String value) {
_surname = value;
},
);
}
Widget _buildAge() {
return TextFormField(
decoration: InputDecoration(labelText: 'Age'),
keyboardType: TextInputType.number,
validator: (String value) {
int age = int.tryParse(value);
if (value.isEmpty) {
return 'Age is required';
}
if (age == null || age <= 0) {
return 'Invalid age';
}
return null;
},
onSaved: (String value) {
_age = value;
},
);
}
Widget _buildGender() {
return DropdownButtonFormField(
items: [
DropdownMenuItem<String>(
value: 'Male',
child: Text('Male'),
),
DropdownMenuItem<String>(
value: 'Female',
child: Text('Female'),
),
DropdownMenuItem<String>(
value: 'Other',
child: Text('Other'),
)
],
validator: (String value) {
if (value == null) {
return 'Gender is required';
}
return null;
},
value: _gender,
decoration: InputDecoration(labelText: 'Gender'),
onChanged: (String value) {
setState(() {
_gender = value;
});
},
);
}
Widget _buildDateOfBirth() {
return TextFormField(
decoration: InputDecoration(labelText: 'Date of Birth'),
validator: (String value) {
if (value.isEmpty) {
return 'Date of birth is required';
}
return null;
},
onTap: () {
// Below line stops keyboard from appearing
FocusScope.of(context).requestFocus(new FocusNode());
// Show Date Picker Here
_selectDate(context);
},
controller: _date,
);
}
Future<Null> _selectDate(BuildContext context) async {
DateFormat formatter =
DateFormat('dd/MM/yyyy'); //specifies day/month/year format
final DateTime picked = await showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(1900),
lastDate: DateTime.now());
if (picked != null && picked != selectedDate)
setState(() {
selectedDate = picked;
_date.value = TextEditingValue(text: formatter.format(picked));
_dateOfBirth = _date.text;
});
}
void nextScreen(BuildContext context) {
Navigator.of(context).push(MaterialPageRoute(
builder: (_) {
return ContactDetailsScreen();
},
));
}
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(24),
child: Form(
key: _personalDetailsFormKey,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_buildTitle(),
_buildFirstName(),
_buildMiddleName(),
_buildSurname(),
_buildAge(),
_buildGender(),
_buildDateOfBirth(),
SizedBox(
height: 50,
),
SizedBox(
width: double.infinity,
child: RaisedButton(
color: Theme.of(context).primaryColor,
onPressed: () {
if (!_personalDetailsFormKey.currentState.validate()) {
return;
}
_personalDetailsFormKey.currentState.save();
nextScreen(context);
},
child: Text(
'Next',
style: TextStyle(color: Colors.white),
),
),
)
],
),
),
),
);
}
}
这是第二页:
import 'package:fact_find_v2/screens/testscreen.dart';
import 'package:flutter/material.dart';
class ContactDetailsForm extends StatefulWidget {
@override
_ContactDetailsFormState createState() => _ContactDetailsFormState();
}
class _ContactDetailsFormState extends State<ContactDetailsForm> {
String _email;
String _phoneNumber;
String _address;
final GlobalKey<FormState> _contactDetailsFormKey = GlobalKey<FormState>();
Widget _buildEmail() {
return TextFormField(
decoration: InputDecoration(labelText: 'Email'),
keyboardType: TextInputType.emailAddress,
validator: (String value) {
if (value.isEmpty) {
return 'Email is required';
}
if (!RegExp(
r"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")
.hasMatch(value)) {
return 'Please enter a valid email address';
}
return null;
},
onSaved: (String value) {
_email = value;
},
);
}
Widget _buildPhoneNumber() {
return TextFormField(
decoration: InputDecoration(labelText: 'Phone Number'),
keyboardType: TextInputType.phone,
validator: (String value) {
if (value.isEmpty) {
return 'Phone number is required';
}
if (!RegExp(r'(^(?:[+0]9)?[0-9]{8,10}$)').hasMatch(value)) {
return 'Please enter a valid phone number';
}
return null;
},
onSaved: (String value) {
_phoneNumber = value;
},
);
}
Widget _buildAddress() {
return TextFormField(
decoration: InputDecoration(labelText: 'Address'),
keyboardType: TextInputType.streetAddress,
// initialValue: _addressController.text,
validator: (String value) {
if (value.isEmpty) {
return 'Address is required';
}
return null;
},
onSaved: (String value) {
_address = value;
});
}
void nextScreen(BuildContext context) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) {
return TestScreen();
},
),
);
}
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(24),
child: Form(
key: _contactDetailsFormKey,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_buildEmail(),
_buildPhoneNumber(),
_buildAddress(),
SizedBox(
height: 50,
),
SizedBox(
width: double.infinity,
child: RaisedButton(
color: Theme.of(context).primaryColor,
onPressed: () {
if (!_contactDetailsFormKey.currentState.validate()) {
return;
}
_contactDetailsFormKey.currentState.save();
nextScreen(
context); //this is the next screen which is just used for debugging
},
child: Text(
'Next',
style: TextStyle(color: Colors.white),
),
),
),
],
),
),
),
);
}
}