flutter form data disappears when I scroll

Issue

I have a widget, that has an image element and and expanded listview of form elements that as I fill out and scroll the data disappears when it scrolls behind the image. It is not throwing any errors when I debug and it happens on any field that scrolls behind the image at the top of the widget. Any ideas?

@override
  Widget build(BuildContext context) {
    var _children = <Widget>[
      new Center(
        child: new Text(widget.prov.fname + widget.prov.lname,
          style: new TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
        ),
      ),
      new Center(
          child: new Container(
            padding: new EdgeInsets.only(
                left: 125.0, right: 125.0, bottom: 50.0),
            child: new Image.network('http://$baseurl:8080/getimage/'+widget.prov.pic.assetName),
          )
      ),

      new Form(
          key: _formKey,
          autovalidate: _autovalidate,
          onWillPop: _warnUserAboutInvalidData,
          child: new Expanded(
              child: new ListView(
                padding: const EdgeInsets.symmetric(horizontal: 16.0),
                children: <Widget>[
                  new TextFormField(
                    decoration: const InputDecoration(
                      icon: const Icon(Icons.person),
                      hintText: 'First Name?',
                      labelText: 'First Name *',
                    ),
                    onSaved: (String value) { referral.fname = value; },
                    validator: _validateName,
                  ),

                  new TextFormField(
                    decoration: const InputDecoration(
                      icon: const Icon(Icons.person),
                      hintText: 'Last Name?',
                      labelText: 'Last Name *',
                    ),
                    onSaved: (String value) { referral.lname = value; },
                    validator: _validateName,
                  ),

                  new TextFormField(
                    decoration: const InputDecoration(
                        icon: const Icon(Icons.phone),
                        hintText: 'How to contact?',
                        labelText: 'Phone Number *',
                        prefixText: '+1'
                    ),
                    keyboardType: TextInputType.phone,
                    onSaved: (String value) { referral.contact = value; },
                    validator: _validatePhoneNumber,
                    // TextInputFormatters are applied in sequence.
                    inputFormatters: <TextInputFormatter> [
                      WhitelistingTextInputFormatter.digitsOnly,
                      // Fit the validating format.
                      _phoneNumberFormatter,
                    ],
                  ),

                  new TextFormField(
                    decoration: const InputDecoration(
                      hintText: 'Tell us about patient',
                      helperText: 'It does not have to be detailed yet',
                      labelText: 'Referral Details',
                    ),
                    maxLines: 5,
                  ),

                  new _DateTimePicker(
                    labelText: 'DOB',
                    selectedDate: _fromDate,
                    selectDate: (DateTime date) {
                      setState(() {
                        referral.dob = date;
                      });
                    },
                  ),

                  new InputDecorator(
                    decoration: const InputDecoration(
                      labelText: 'Type of Appointment',
                      hintText: 'Choose an Appointment Type',
                    ),
                    isEmpty: _typeAppt == null,
                    child: new DropdownButton<String>(
                      value: _typeAppt,
                      isDense: true,
                      onChanged: (String newValue) {
                        setState(() {
                          _typeAppt = newValue;
                        });
                      },
                      items: _allTypeAppt.map((String value) {
                        return new DropdownMenuItem<String>(
                          value: value,
                          child: new Text(value),
                        );
                      }).toList(),
                    ),
                  ),

                ],

              )
          )
      ),

      /*new RefreshIndicator(
        child: new ListView.builder(
          itemBuilder: _itemBuilder,
          itemCount: listcount,
        ),
        onRefresh: _onRefresh,

      ),*/

    ];
    return new Scaffold(
      appBar: new AppBar(title: new Text("My Provider")),
      body: new Column(
        children: _children,
      ),
    );
  }

Solution

I think the problem is that you don’t save the values which were put into the TextFields (to a state for example).
From your code I assume you are using the ListView.builder() to set up your ListView. This method, as stated in the documentation, renders only the children, which are in view. Once you scroll a child out of view, it is removed from the ListView and only added again, once you scroll it into view. Because the TextField is removed, the value is removed as well.

To permanently have the value saved, I would advice to use TextFields and save the input to state in the onChanged() method of the TextField, or make use of TextEditingController.

Answered By – Rainer Wittmann

Answer Checked By – Katrina (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *