TextFormField losing its value when scrolled up and inside a listview

839 views
Skip to first unread message

mahe...@prayuta.com

unread,
Sep 22, 2017, 6:43:19 AM9/22/17
to Flutter Dev
Hello DevTeam,

I have a strange problem in my application I have a signup page with several textformfields inside a ListView and the ListView is a child to the Form.

when i reach the last formfield inside the ListView i need to scroll up the screen to actually see what i am typing inside the field. When i do scroll up the textformfields which go out of focus are losing the entered text and are initialised as null. I am not sure what i am missing or do i have to use some other way to make sure i retain the TextFormField values. I have tried to use the controller in every TextFormField then it is retaining the value even if I scroll up. But, the properties of the object e.g, hostelData.hostelName are only updated first time and the changes are not reflected in the object property from the second time. I am not so sure what i am missing? Please can someone help me in solving this. 
Please excuse my mistakes in posting as i am new to programming and any help would be greatly appreciated.

I have posted the code below so that you can reproduce the same problem.

     

     import 'dart:async';

     import 'package:firebase_auth/firebase_auth.dart';
     import 'package:firebase_database/firebase_database.dart';
     import 'package:flutter/material.dart';
     import 'package:flutter/rendering.dart';
     import 'package:flutter/widgets.dart';     
     import 'package:myhostel/theme.dart' as Theme;
     import 'package:myhostel/globals.dart' as gl;
     
     class SignUp extends StatefulWidget {
     const SignUp({ Key key }) : super(key: key);
     @override
      _SignUpState createState() => new _SignUpState();
      }
   
    class HostelData{
     String hostelName = '';
     String ownersName = '';
     String mobileNumber = '';
     String emailId = '';
     String password = '';
     String city = '';
     String hostelType= 'mens';
     String confirmPassword ='';
     }
    class _SignUpState extends State<SignUp> {
     HostelData hostelData = new HostelData();

    void showInSnackBar(String value) {
    _scaffoldKey.currentState.showSnackBar(new SnackBar(
        content: new Text(value),
      duration: const Duration(milliseconds: 3000),

      ));
    }
       
    final GlobalKey<FormState> _formKey = new GlobalKey<FormState>();
    final GlobalKey<FormFieldState<String>> _passwordFieldKey = new 
    GlobalKey<FormFieldState<String>>();
    bool _autovalidate = false;
    bool _formWasEdited = false;
 
     void _handleSubmitted() {
      final FormState form = _formKey.currentState;
     if (!form.validate()) {
       _autovalidate = true;  // Start validating on every change.
       showInSnackBar('Please fix the errors in red before submitting.');
       } else {
         form.save();
          showInSnackBar('${hostelData.ownersName}\'s hostel name is 
                 ${hostelData.hostelName}');
                _createuserwithemailandpassword();
         }
       }
       String _validateName(String value) {
        _formWasEdited = true;
         if (value.isEmpty)
         return 'Name is required.';
         final RegExp nameExp = new RegExp(r'^[A-Za-z ]+$');
         if (!nameExp.hasMatch(value))
         return 'Please enter only alphabetical characters and spaces.';
         return null;
        }
        String _validatePassword(String value) {
          _formWasEdited = true;
           final FormFieldState<String> passwordField = 
           _passwordFieldKey.currentState;
         if (passwordField.value == null || passwordField.value.isEmpty)
         return 'Please choose a password.';
        if (passwordField.value != value)
         return 'Passwords don\'t match';
         return null;
          }
         @override
         Widget build(BuildContext context){

       return new MaterialApp(
       theme: Theme.MyHostelThemeData,
       home: new Scaffold(
        key: _scaffoldKey,
        
        body: new Container(
          child: new Container(
          decoration: new BoxDecoration(
              image: new DecorationImage(
                  image: new AssetImage('assets/bg.png'),
                fit: BoxFit.fill,
              ),
          ),
          child: new Form(

            key: _formKey,
            autovalidate: _autovalidate,
           

           child: new ListView(
             children: <Widget>[
              new Container(
                margin: const EdgeInsets.only(top:32.0),
                child: new Center(
                  child: new Text('SIGN UP',
                  style: new TextStyle(
                      color: const Color(0xFFF5FEFD),fontSize:24.0,fontWeight: 
                 FontWeight.bold),
                ),
              ),
              ),
          new Row(
                children:[
                  
                  
          new Expanded(
          child: new Container(
            margin: const EdgeInsets.only(left: 24.0,right: 12.0,),

            child:new TextFormField(decoration: new InputDecoration(
                /*hintStyle: new TextStyle(
                  fontSize: 20.0,color: const Color(0xFFF5FEFD),),*/
                labelText: 'Hostel Name',
              ),
              /*style: new TextStyle(
                fontSize: 20.0,
                color:  Colors.white,
              ),*/

              onSaved:(String value){ hostelData.hostelName = value; },
              validator: _validateName,
             ),
           ),
          ),
         ],
         ),
         new Row(
                children:[
                  /*new Container(
                    margin: const EdgeInsets.all(8.0),
                    width: 24.0,
                    child: new Image.asset(
                      'assets/person_avatar.png',
                      fit: BoxFit.contain,
                      //alignment: FractionalOffset.center,
                    ),
                  ),*/
                  
                  new Expanded(
                    child: new Container(
                      margin: const EdgeInsets.only(left: 24.0,right: 12.0,),

                      child:new TextFormField(
                        //controller: _ownersNameController,

                        decoration: new InputDecoration(//hintText: 'Mobile 
                 Number',
                         /* hintStyle: new TextStyle(fontSize: 20.0,color: const 
              Color(0xFFF5FEFD),),*/
                          labelText: 'Owners Name',
                        ),

                        /*style: new TextStyle(
                          fontSize: 20.0,
                          color:  Colors.white,
                        ),*/
                     onSaved: (String value) { hostelData.ownersName = value; 
                                                                            },
                        validator: _validateName,
                      ),
                    ),
                  ),
                ],
              ), 
           new Row(
                children:[

                  

                  new Expanded(
                    child: new Container(
                      margin: const EdgeInsets.only(left: 24.0,right: 12.0,),

                      child:new TextFormField(
                        //controller: _mobileNumberController,
                        keyboardType: TextInputType.phone,

                        decoration: new InputDecoration(//hintText: 'Mobile 
                         Number',
                          /* hintStyle: new TextStyle(fontSize: 20.0,color: 
                            const Color(0xFFF5FEFD),),*/
                          labelText: 'Mobile Number',
                          //prefixText: '+91',
                        ),

                        /*style: new TextStyle(
                          fontSize: 20.0,
                          color:  Colors.white,
                        ),*/
                   onSaved: (String value) { hostelData.mobileNumber = value; },
                        //validator: _validatePhoneNumber,
                      ),
                    ),
                  ),
                ],
              ),
          //implements EmailID Row
              new Row(
                children:[
                  

                  new Expanded(
                    child: new Container(
                      margin: const EdgeInsets.only(left: 24.0,right: 12.0,),

                      child:new TextFormField(
                        //controller: _emailIdController,

                        decoration: new InputDecoration(
                          //hintText: 'Mobile Number',
                          /*hintStyle: new TextStyle(fontSize: 20.0,color: const 
                                Color(0xFFF5FEFD),),*/
                          labelText: 'EMail Id',
                          helperText: 'Required',
                        ),
                        /*style: new TextStyle(
                          fontSize: 20.0,
                          color:  Colors.white,
                        ),*/
                        onSaved: (String value){hostelData.emailId = value;},
                      ),
                    ),
                  ),
                ],
              ),
          //implements the password row

              new Container(
                padding: const EdgeInsets.only(left: 8.0,),
                child: new Row(
                  children: <Widget>[
                    new Container(
                      margin: const EdgeInsets.only(top: 16.0),
                      //padding: const EdgeInsets.all(8.0),
                      child: new Icon(Icons.lock_outline,
                          color: const Color(0xFFF5FEFD)
                      ),
                    ),
                    new Expanded(
                      child: new Container(
                        margin: const EdgeInsets.only(
                          left: 28.0, right: 12.0,),
                        child: new TextFormField(
                          key: _passwordFieldKey,
                          //controller: _passwordController,
                          decoration: const InputDecoration(
                            hintText: 'min 8 characters',
                            labelText: 'Password',
                              helperText: 'Required',

                          ),
                          autocorrect: false,
                          //obscureText: true,
                          //validator: 'Required',
                          /*style: DefaultTextStyle.of(context).style.merge(new 
                                           TextStyle(
                                  fontSize: 16.0,
                                  color: CustomColors.fontColor,
                                ),
                                ),*/
                          onSaved: (String value){hostelData.password = value;},

                        ),
                      ),
                    ),
                  ],
                ),
              ),
               new Container(
                padding: const EdgeInsets.only(left: 8.0,),
                child: new Row(
                  children: <Widget>[
                    new Container(
                      margin: const EdgeInsets.only(top: 16.0),
                      //padding: const EdgeInsets.all(8.0),
                      child: new Icon(Icons.lock_outline,
                          color: const Color(0xFFF5FEFD)
                      ),
                    ),
                    new Expanded(
                      child: new Container(
                        margin: const EdgeInsets.only(
                          left: 28.0, right: 12.0,),
                        child: new TextFormField(
                          //controller: _confirmpasswordcontroller,
                          decoration: const InputDecoration(
                            labelText: 'Confirm Password',
                           helperText: 'Required'


                          ),
                          autocorrect: false,
                         // obscureText: true,
                          //validator: 'Required',
                          /*style: DefaultTextStyle.of(context).style.merge(new 
                        TextStyle(
                                  fontSize: 16.0,
                                  color: CustomColors.fontColor,
                                ),
                                ),*/
                          //onSaved: (String value){hostelData.confirmPassword = 
                                                    value;},

                          validator: _validatePassword,
                        ),
                      ),
                    ),
                  ],
                ),
              ),
              new Row(
                children:[

                  new Expanded(
                    child: new Container(
                      margin: const EdgeInsets.only(left: 24.0,right: 12.0,),

                      child:new TextFormField(
                        controller: _cityController,

                        decoration: new InputDecoration(labelText: 'City*'),

                        onSaved: (String value){hostelData.city = value;},
                        validator: _validateName,
                      ),
                    ),
                  ),
                ],
              ),
             new Container(
                padding: const EdgeInsets.all(8.0),
                margin: const EdgeInsets.only(left:24.0,right: 24.0),
                decoration: new BoxDecoration(
                  border: new Border.all(
                    color: Colors.white,
                    width: 2.0,
                  ),
                  borderRadius: new BorderRadius.all(const 
                        Radius.circular(32.0),)
                ),
            child: new FlatButton(
              onPressed: ((){
                print('SignUp Button Clicked');
                 _handleSubmitted();
              }),
              child: new Text (
                'SIGN UP',
                style: new TextStyle(fontSize: 24.0,
                  fontWeight: FontWeight.bold,
                  color: Colors.white,
                ),
              ),
            ),
           ),
              new Row(
                children:[


                    new Container(
                      margin: const EdgeInsets.only(left: 24.0,bottom: 12.0),

                      child:new Text(
                        'Already have an account?',
                           style: new TextStyle(
                          fontSize: 20.0,
                          color:  Colors.white,
                        ),
                      ),
                    ),

                  new Container(
                    padding: const EdgeInsets.only(right: 8.0,top: 
                        4.0,bottom:16.0),
                    margin: const EdgeInsets.only(right: 12.0,left: 4.0),
                    child:
                  new MaterialButton(
                    onPressed: ((){
                    //Sign In Button pressed declaration here
                    print('sign in button clicked');
                    
                  }),
                      child: new Text('SignIn',
                      style: new TextStyle(
                        fontSize: 16.0,
                        color: Colors.teal[200],
                        ),
                         ),
                    minWidth: 16.0,
                  ),
                  ),

                ],
              ),
              new Container(
                padding: const EdgeInsets.only(left: 16.0),
                child: new Text('* indicates required field',
                    style: new TextStyle(
                      fontSize: 14.0,
                      color: Colors.white,
                    ),),
              ),
           ]
          ),
           ),
          ),

         ),
 
        ),

        );
 
      } // widget ends here
       

globals.dart

    library my_hostel.globals;

     import 'package:firebase_auth/firebase_auth.dart';
     import 'package:firebase_database/firebase_database.dart';



       final FirebaseAuth auth = FirebaseAuth.instance;
          
     final DatabaseReference messagesRef =FirebaseDatabase.instance.reference();

Ian Hickson

unread,
Oct 6, 2017, 8:08:24 PM10/6/17
to mahe...@prayuta.com, Flutter Dev
Sounds like https://github.com/flutter/flutter/issues/11500
It's on our list of things to work on in our current milestone (as are many other issues!). Don't hesitate to mark it with a thumbs up if you want to indicate your concern, that will help us prioritise it.

--
You received this message because you are subscribed to the Google Groups "Flutter Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to flutter-dev...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--

--
Ian Hickson

😸
Reply all
Reply to author
Forward
0 new messages