我如何从Stepper TextFields中获取数据...无论字段如何,总是返回null。在这种情况下,我正在使用电子邮件进行测试。我遵循Aseem Wangoo的方法,该方法似乎在以下链接中:here。并用于我的解决方案如下:
List<GlobalKey<FormState>> formKeys = [GlobalKey<FormState>(), GlobalKey<FormState>()];
class MyData {
String _password;
String _email;
String _name;
String _lastname;
}
class _SigninState extends State<Signin> {
GlobalKey<FormState> _formKey = GlobalKey<FormState>();
static var _focusNode = FocusNode();
static MyData data = new MyData();
@override
void initState() {
super.initState();
_focusNode.addListener(() {
setState(() {});
print('Has focus: $_focusNode.hasFocus');
});
}
@override
void dispose() {
_focusNode.dispose();
super.dispose();
}
List<Step> steps = [
Step(
title: const Text('Crear cuenta'),
isActive: true,
state: StepState.indexed,
content: Form(
key: formKeys[0],
child: Column(
children: <Widget>[
TextFormField(
focusNode: _focusNode,
autocorrect: false,
onSaved: (String value) {
data._email = value;
},
maxLines: 1,
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value.isEmpty || value.length < 1) {
return 'Please enter name';
}
},
decoration: InputDecoration(labelText: 'Correo electrónico'),
),
TextFormField(
validator: (value) {
if (value.isEmpty) {
return 'Ingrese su contraseña';
}
return null;
},
obscureText: true,
autocorrect: false,
onSaved: (String value) {
data._password = value;
},
decoration: InputDecoration(labelText: 'Contraseña'),
),
],
),
)
),
Step(
isActive: true,
state: StepState.indexed,
title: const Text('Nombre y Apellido'),
content: Form(
key: formKeys[1],
child: Column(
children: <Widget>[
TextFormField(
onSaved: (String value) {
data._name = value;
},
autocorrect: false,
decoration: InputDecoration(labelText: 'Nombre'),
),
TextFormField(
onSaved: (String value) {
data._password = value;
},
autocorrect: false,
decoration: InputDecoration(labelText: 'Apellido'),
),
],
),
)
),
];
int currentStep = 0;
bool complete = false;
next() {
currentStep + 1 != steps.length
? goTo(currentStep + 1)
: setState(() => complete = true);
}
cancel() {
if (currentStep > 0) {
goTo(currentStep - 1);
}
}
goTo(int step) {
setState(() => currentStep = step);
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: Stack(children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
MustardColor,
FlanColor,
FlanLightColor
],
stops: [0.1, 0.9, 1.5]
)
)
),
Container(
height: 180.0,
width: 320.0,
child: Image.asset('assets/images/crypto.png'),
margin: const EdgeInsets.only(left: 50.0, right: 50.0, top: 20.0, bottom: 50.0),
),
Center(child:
Container(
height: 480.0,
width: 320.0,
margin: const EdgeInsets.only(top: 100.0),
decoration: BoxDecoration(
color: FlanLightColor,
borderRadius: BorderRadius.circular(25)
),
)
),
Container(
height: 80.0,
width: 200.0,
child: Text('Regístrate',
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 30,
fontWeight: FontWeight.w600
),
),
margin: const EdgeInsets.only(left: 120.0, right: 120.0, top: 180.0, bottom: 100.0),
),
// STEPPER
Center(
child: Container(
margin: const EdgeInsets.only(top: 100),
height: 380.0,
width: 300.0,
child: Form(
key: _formKey,
child:
Column(
children: <Widget>[
Expanded(
child: Stepper(
steps: steps,
currentStep: currentStep,
onStepContinue: next,
onStepTapped: (step) => goTo(step),
onStepCancel: cancel,
controlsBuilder: (BuildContext context,
{VoidCallback onStepContinue, VoidCallback onStepCancel}) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(
height: 80.0,
),
FlatButton(
color: MustardColor,
onPressed: currentStep == 0 ? onStepContinue : () async {
onStepContinue();
// save the fields..
final FormState formState = _formKey.currentState;
if (!formState.validate()) {
print('Please enter correct data');
} else {
formState.save();
print("Email: ${data._email}"); // THIS RETURNS Email: Null
}
},
child: currentStep == 0 ? const Text('SIGUIENTE') : const Text('FINALIZAR'),
),
FlatButton(
color: GoldColor,
onPressed: onStepCancel,
child: const Text('CANCELAR'),
),
],
);
},
)
),
])
)
))
],)
);
}
}
我的错误是什么?既不接收字段的值,也不在验证每个步骤。 最佳答案
使用TextEditingController
class _SigninState extends State<Signin> {
GlobalKey<FormState> _formKey = GlobalKey<FormState>();
static var _focusNode = FocusNode();
static MyData data = new MyData();
static TextEditingController _emailController = new TextEditingController();
static TextEditingController _passwordController = new TextEditingController();
static TextEditingController _nameController = new TextEditingController();
static TextEditingController _lastnameController = new TextEditingController();
@override
void initState() {
super.initState();
_focusNode.addListener(() {
setState(() {});
print('Has focus: $_focusNode.hasFocus');
});
}
@override
void dispose() {
_focusNode.dispose();
super.dispose();
}
List<Step> steps = [
Step(
title: const Text('Crear cuenta'),
isActive: true,
state: StepState.indexed,
content: Form(
key: formKeys[0],
child: Column(
children: <Widget>[
TextFormField(
focusNode: _focusNode,
autocorrect: false,
onSaved: (String value) {
data._email = value;
},
maxLines: 1,
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value.isEmpty || value.length < 1) {
return 'Please enter name';
}
},
controller: _emailController,
decoration: InputDecoration(labelText: 'Correo electrónico'),
),
TextFormField(
validator: (value) {
if (value.isEmpty) {
return 'Ingrese su contraseña';
}
return null;
},
obscureText: true,
autocorrect: false,
onSaved: (String value) {
data._password = value;
},
controller: _passwordController,
decoration: InputDecoration(labelText: 'Contraseña'),
),
],
),
)
),
Step(
isActive: true,
state: StepState.indexed,
title: const Text('Nombre y Apellido'),
content: Form(
key: formKeys[1],
child: Column(
children: <Widget>[
TextFormField(
onSaved: (String value) {
data._name = value;
},
autocorrect: false,
controller: _nameController,
decoration: InputDecoration(labelText: 'Nombre'),
),
TextFormField(
onSaved: (String value) {
data._password = value;
},
controller: _passwordController,
autocorrect: false,
decoration: InputDecoration(labelText: 'Apellido'),
),
],
),
)
),
];
int currentStep = 0;
bool complete = false;
next() {
currentStep + 1 != steps.length
? goTo(currentStep + 1)
: setState(() => complete = true);
}
cancel() {
if (currentStep > 0) {
goTo(currentStep - 1);
}
}
goTo(int step) {
setState(() => currentStep = step);
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: Stack(children: <Widget>[
Container(
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.blueAccent,
Colors.amber,
Colors.red
],
stops: [0.1, 0.9, 1.5]
)
)
),
Container(
height: 180.0,
width: 320.0,
child: Image.asset('assets/images/crypto.png'),
margin: const EdgeInsets.only(left: 50.0, right: 50.0, top: 20.0, bottom: 50.0),
),
Center(child:
Container(
height: 480.0,
width: 320.0,
margin: const EdgeInsets.only(top: 100.0),
decoration: BoxDecoration(
color: Colors.cyan,
borderRadius: BorderRadius.circular(25)
),
)
),
Container(
height: 80.0,
width: 200.0,
child: Text('Regístrate',
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 30,
fontWeight: FontWeight.w600
),
),
margin: const EdgeInsets.only(left: 120.0, right: 120.0, top: 180.0, bottom: 100.0),
),
// STEPPER
Center(
child: Container(
margin: const EdgeInsets.only(top: 100),
height: 380.0,
width: 300.0,
child: Form(
key: _formKey,
child:
Column(
children: <Widget>[
Expanded(
child: Stepper(
steps: steps,
currentStep: currentStep,
onStepContinue: next,
onStepTapped: (step) => goTo(step),
onStepCancel: cancel,
controlsBuilder: (BuildContext context,
{VoidCallback onStepContinue, VoidCallback onStepCancel}) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(
height: 80.0,
),
FlatButton(
color: Colors.green,
onPressed: currentStep == 0 ? onStepContinue : () async {
onStepContinue();
// save the fields..
final FormState formState = _formKey.currentState;
if (!formState.validate()) {
print('Please enter correct data');
} else {
formState.save();
print("Email: ${_emailController.value.text}"); // THIS RETURNS Email: Null
}
},
child: currentStep == 0 ? const Text('SIGUIENTE') : const Text('FINALIZAR'),
),
FlatButton(
color: Colors.amber,
onPressed: onStepCancel,
child: const Text('CANCELAR'),
),
],
);
},
)
),
])
)
))
],)
);
}
}
关于flutter - Flutter从Stepper TextFields获取数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63460629/