Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter - TextField loses value on focus out

I have two TextField within a container. The first is defined as TextInputType.text and the second is TextInputType.number. Whenever I change focus (First<>Second or Second<>First), the TextField that loses focus also loses its value.

Strangely, both textFields works if I define both of them as TextInputType.text, if I set one of them as anything but TextInputType.text, both loses the typed value on focus out.

Very annoying. I have no idea why this happens.

It is a Flutter bug or am I doing something wrong?

This is the widget code:

class LoginInput extends StatelessWidget {
  final String hintText;
  final IconData icon;
  final String iconTag;
  final TextEditingController controller;
  final TextInputType inputType;
  final bool obscureText;

  LoginInput(this.hintText, this.icon, this.iconTag, this.controller,
      this.inputType, this.obscureText);

  @override
  Widget build(BuildContext context) {
    return new Column(children: <Widget>[
      new Container(
          height: 56.0,
          child: new Material(
              borderRadius: BorderRadius.all(Radius.circular(5.0)),
              elevation: 0.0,
              color: Colors.white,
              child: new Container(
                  child: new ListTile(
                leading: new Hero(
                    tag: iconTag, child: new Icon(icon, color: Colors.black)),
                title: new TextField(

                  keyboardType: inputType,
                  obscureText: obscureText,
                  textInputAction: TextInputAction.send,
                  controller: controller,
                  decoration: new InputDecoration(
                    border: InputBorder.none,
                    hintText: hintText,
                  ),
                  style: new TextStyle(
                      color: Colors.black,
                      fontSize: 18.0,
                      fontFamily: 'Caecilia',
                      fontWeight: FontWeight.w500),
                ),
              )))),
      new Divider(height: 0.0, color: Theme.of(context).dividerColor),
    ]);
  }
}

This is how is called:

  final LoginInput nameField = new LoginInput("Full name", Icons.face, "leading_icon_name", new TextEditingController(), TextInputType.text,false);

  final LoginInput birthField = new LoginInput("Birth date", Icons.date_range, "leading_icon_birth", new TextEditingController(), TextInputType.number, false);
like image 551
Notheros Avatar asked Aug 13 '18 11:08

Notheros


3 Answers

I just faced the same issue and the solution was to transform my Widget from a Stateless to a Stateful one.

The last comment in this thread might help with your issue.

like image 152
Dunowen Avatar answered Nov 09 '22 21:11

Dunowen


If you move your

final TextEditingController controller;

out of the class, the content of the TextField will not be reset each time the TextField lose its focus.

Aplying this to your code:

final TextEditingController controller;

class LoginInput extends StatelessWidget {
  final String hintText;
  final IconData icon;
  final String iconTag;
  final TextInputType inputType;
  final bool obscureText;

  LoginInput(this.hintText, this.icon, this.iconTag, this.inputType, this.obscureText);

  @override
  Widget build(BuildContext context) {
    return new Column(children: <Widget>[
      new Container(
          height: 56.0,
          child: new Material(
              borderRadius: BorderRadius.all(Radius.circular(5.0)),
              elevation: 0.0,
              color: Colors.white,
              child: new Container(
                  child: new ListTile(
                leading: new Hero(
                    tag: iconTag, child: new Icon(icon, color: Colors.black)),
                title: new TextField(

                  keyboardType: inputType,
                  obscureText: obscureText,
                  textInputAction: TextInputAction.send,
                  controller: controller,
                  decoration: new InputDecoration(
                    border: InputBorder.none,
                    hintText: hintText,
                  ),
                  style: new TextStyle(
                      color: Colors.black,
                      fontSize: 18.0,
                      fontFamily: 'Caecilia',
                      fontWeight: FontWeight.w500),
                ),
              )))),
      new Divider(height: 0.0, color: Theme.of(context).dividerColor),
    ]);
  }
}
like image 21
user12475565 Avatar answered Nov 09 '22 23:11

user12475565


If you are now running with a statefulWidget and something can re-render your view such as: PageView or your logic. You should use TextEditingController

Remember to dispose it.

Inside your statefulWidget

class _MainViewState extends State<_MainView> {

PageController _pageController;
TextEditingController _textController;

  @override
  void initState() {
    _pageController = PageController(keepPage: true, initialPage: 2);
    _textController = TextEditingController();
    super.initState();
  }

  @override
  void dispose() {
    _pageController.dispose();
    _textController.dispose();
    super.dispose();
  }

  ...

  TextField( 
     controller: _textController, //Add controller to your TextField
     onChanged: (v) {
        //do something
     },
     ...
  ),

}

From now, you can trigger value of TextField from _textController.text or onChanged function depends on your need.

like image 2
ANDYNVT Avatar answered Nov 09 '22 21:11

ANDYNVT