I am getting some strange issue where one of TextField always gets clears if you tap on it.
class MyEditText extends StatefulWidget {
static String tag = "MyEditText";
@override
MyEditTextState createState() => MyEditTextState();
}
class MyEditTextState extends State<MyEditText> {
String results = "";
final TextEditingController controller = new TextEditingController();
final TextEditingController controller1 = new TextEditingController();
@override
Widget build(BuildContext context) {
final email = TextField(
decoration: InputDecoration(
hintText: 'Enter Email',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0)),
);
final password = TextField(
obscureText: true,
decoration: InputDecoration(
hintText: 'Enter Password',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
),
);
return new Scaffold(
appBar: new AppBar(
automaticallyImplyLeading: false,
title: new Text("EditText Sample"),
backgroundColor: Colors.yellow,
),
body: new Container(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[email, password],
),
),
);
}
}
I am using statful widget for it and all classes from where this screen launch also statful.
Note: If I comment out all TextEditingController and its usage, everything works fine, SO I m not getting what is wrong with TextEditingController
Thanks for the updated code.
The reason your TextEditingController
get cleared is because you declare the variables inside of State<MyEditText>
. When the State gets re-initialized - those variables do, too.
I can see 2 ways to solve this:
Controllers are declared and maintained outside of MyEditText
widget - in the parent class.
class MyEditText extends StatefulWidget {
MyEditText({ Key key, this.emailController, this.passwordController }): super(key: key);
final TextEditingController emailController;
final TextEditingController passwordController;
static String tag = "MyEditText";
@override
MyEditTextState createState() => MyEditTextState();
}
class MyEditTextState extends State<MyEditText> {
String results = "";
@override
Widget build(BuildContext context) {
// ...
TextField(
controller: widget.emailController,
// ...,
),
TextField(
controller: widget.passwordController,
// ...,
),
// ...
}
}
Then you declare controllers in your parent class and pass them as arguments to MyEditText
:
final emailController = TextEditingController();
final passwordController = TextEditingController();
// ...
MyEditText(
emailController: emailController,
passwordController: passwordController,
)
didUpdateWidget
callControllers can be declared outside of MyEditText
class, but if they were not - widget creates and maintains TextEditingController
on its own.
class MyEditText extends StatefulWidget {
MyEditText({ Key key, this.emailController, this.passwordController }): super(key: key);
final TextEditingController emailController;
final TextEditingController passwordController;
static String tag = "MyEditText";
@override
MyEditTextState createState() => MyEditTextState();
}
class MyEditTextState extends State<MyEditText> {
TextEditingController _emailController;
TextEditingController _passwordController;
@override
void initState() {
super.initState();
if (widget.emailController == null)
_emailController = TextEditingController();
if (widget.passwordController == null)
_passwordController = TextEditingController();
}
@override
void didUpdateWidget(MyEditText oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.emailController == null && oldWidget.emailController != null)
_emailController = TextEditingController.fromValue(oldWidget.emailController.value);
else if (widget.emailController != null && oldWidget.emailController == null)
_emailController = null;
if (widget.passwordController == null && oldWidget.passwordController != null)
_passwordController = TextEditingController.fromValue(oldWidget.passwordController.value);
else if (widget.passwordController != null && oldWidget.passwordController == null)
_passwordController = null;
}
@override
Widget build(BuildContext context) {
// ...
TextField(
controller: _emailController ?? widget.emailController,
// ...,
),
TextField(
controller: _passwordController ?? widget.passwordController,
// ...,
),
// ...
}
// ...
}
Both methods are similar except that the second one regulates State<MyEditText>
variables on its own.
I will leave it to you to decide which one is more suitable in your case.
Let me know if this helped.