Reputation: 13
I have this Widget to register. Inside I want to ask for 6 inputs to register, but as not too much space on the screen, I splitted in 2 pair of 3. I show three at first in a form and when the user press the continue button I show the other 3. However, when I press the continue button, the new 3 pair of TextField appear with the same value of the previous ones. And they move position a little under. I don't know why it happens since each of those 6 fields is different Widget function.
I created two variables form1 and form2 to hold the different forms
@override
void initState() {
super.initState();
form1 = <Widget>[
firstForm(),
Text("Or Sign Up with social media"),
SizedBox(
height: 20,
),
socialMediaButtons(),
SizedBox(
height: 50,
),
Text("Have an account? Login")
];
form2 = <Widget>[
secondForm(),
Text("Or Sign Up with social media"),
SizedBox(
height: 20,
),
socialMediaButtons(),
SizedBox(
height: 50,
),
Text("Have an account? Login")
];
}
All the text field have the same format as the text field below, I only changed the variable for their respecting field.
Widget firstNameField() {
return TextFormField(
initialValue: "",
decoration: InputDecoration(
contentPadding: EdgeInsets.only(top: 10, left: 20, right: 20),
border: InputBorder.none,
hintText: "First Name",
hintStyle: TextStyle(color: Colors.grey[400], fontSize: 15)),
onChanged: (val) {
setState(() => firstName = val);
},
);
}
I combined the text fields in two widgets (firstForm and secondForm). (Shown firstForm but it is the same format as second, just called the functions for the other widgets).
Widget firstForm() {
return Column(
children: <Widget>[
emailPassField(),
SizedBox(
height: 50,
),
continueButton(),
SizedBox(
height: 50,
),
],
);
}
Then this is the continue button widget which when pressed. show the second form. I change the step variable to 2 to go to the second form.
Widget continueButton() {
return ButtonTheme(
minWidth: 185.0,
height: 48.0,
child: RaisedButton(
color: Colors.black,
textColor: Colors.white,
child: Text("continue"),
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(50.0)),
onPressed: () => setState(() => step = 2),
));
}
When the variable step is changed, I created this function (getForm) to be called and to show the correct form array variable for the children of the column.
@override
Widget build(BuildContext context) {
return Material(
child: Expanded(
child: Stack(
children: <Widget>[
// banner with picture
Positioned(
child: banner(),
),
// Login Elements Container
Positioned(
child: Container(
margin: EdgeInsets.only(top: 300.0),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 5,
blurRadius: 20,
offset: Offset(0, 0))
],
borderRadius: BorderRadius.only(
topRight: Radius.circular(50),
topLeft: Radius.circular(50))),
child: Center(
child: Column(
children: getForm(step),
),
),
),
)
],
),
),
);
}
//functions for switching forms
getForm(int form) {
if (form == 1) {
return form1;
} else if (form == 2) {
return form2;
}
}
This is how the first step of the form appear. first form
If I don't enter any data in the text fields and press the continue button, the second form with the correct text fields will appear as shown in this below image. You can see that they have the correct hint text. second form
However if I enter some data on the first step of the form (seen in second form with data step 1), and then press the continue button, in the second step, the text fields will move down a little bit and the same value entered in the previous text fields will appear in the others too(second form with data step 2). can someone help me please, I don't what's going on there? I hope you understand the code and be able to help me please.
second form with data step 1 second form with data step 2
Upvotes: 1
Views: 1703
Reputation: 1186
Use a unique TextEditingcontroller
for each textfield
...by this way the values won't overlap each others textfield value.
Upvotes: 1
Reputation: 3077
You need to create a TextEditingController
for each TextFormField
.
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
...
final _cityController = TextEditingController();
...
// initState
...
// dispose of all TextEditingControllers
@override
void dispose {
_emailController.dispose();
...
_cityController.dispose();
super.dispose();
}
// do this for every TextFormField
Widget firstNameField() {
return TextFormField(
// pass the corresponding controller, no need to set initial value if empty
controller: _firstNameController,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(top: 10, left: 20, right: 20),
border: InputBorder.none,
hintText: "First Name",
hintStyle: TextStyle(color: Colors.grey[400], fontSize: 15)),
onChanged: (val) {
setState(() => firstName = val);
},
);
}
Upvotes: 1