0

I have this simple widget showing a textfield from which I modify a List:

Widget _elementTextField() {
    final TextEditingController inputNewElement = new TextEditingController();
    return Expanded(
      flex: 3,
      child: Padding(
        padding: EdgeInsets.fromLTRB(0, 16.0, 16.0, 16.0),
        child: Container(
          child: TextField(
            controller: inputNewElement,
            decoration: InputDecoration(labelText: "Add Element"),
            onSubmitted: (elem) {
              // method 1 to update UI
              /*setState(() {
                newSet.elements.add(elem);
              });*/
              // method 2 not updating UI
              // newSet.elements.add(elem);

              print(newSet.elements);
              inputNewElement.clear();
            },
          ),
        ),
      ),
    );
  }

If I uncomment any of those method I won't see the print and the input won't clean up.

This is not related to any other widget and the List is just a simple List with one value on it.

This works fine with other widget I have but on that case I modify the value on a global provider. This is using just a StateFul widget

6
  • can you post code for whole widget? Commented Jan 14, 2020 at 11:37
  • the whole widget is quite big cause includes a swiper with different widgets in it. I moved the controller inside class _NewSetPageState extends State<NewSetPage> { which is the main one and this loads _elementTextField() Commented Jan 14, 2020 at 11:51
  • It's confusing just to see half code, you see. if possible just create a mini version of your widget which reproduces the same problem... so that we can help you out properly. Commented Jan 14, 2020 at 12:02
  • makes sense. Let me create a smaller version and I'll share the whole thing Commented Jan 14, 2020 at 12:27
  • 1
    I'm glad you found the cause and the solution for it. Commented Jan 15, 2020 at 5:09

3 Answers 3

1

Try to remove final TextEditingController inputNewElement = new TextEditingController(); from _elementTextField()

import 'package:flutter/material.dart';

class SamplePage extends StatefulWidget {

    SamplePage({Key key}) : super(key: key);

    @override
    State<StatefulWidget> createState() => SamplePageState();

}

class SamplePageState extends State<SamplePage> {

    final List<String> list = List();
    final TextEditingController inputNewElement = new TextEditingController();

    @override
    void initState() {
        super.initState();
    }

    @override
    void dispose() {
        inputNewElement.dispose();
        super.dispose();
    }

    @override
    Widget build(BuildContext context) {
        return Scaffold(
            body: Column(
                children: <Widget>[
                    Row(children: <Widget>[_elementTextField()]),
                    Text(list.isEmpty ? 'Empty' : list.toString()),
                ],
            )
        );
    }

    Widget _elementTextField() {
//        final TextEditingController inputNewElement = new TextEditingController();
        return Expanded(
            flex: 3,
            child: Padding(
                padding: EdgeInsets.fromLTRB(0, 16.0, 16.0, 16.0),
                child: Container(
                    child: TextField(
                        controller: inputNewElement,
                        decoration: InputDecoration(labelText: "Add Element"),
                        onSubmitted: (elem) {
                            setState(() {
                                list.add(elem);
                            });
                            print(list);
                            inputNewElement.clear();
                        },
                    ),
                ),
            ),
        );
    }

}
Sign up to request clarification or add additional context in comments.

2 Comments

I moved the controller as you suggested and try both method and none of them worked
I have updated my post and add more detail, basically a widget. Please, avoid call _elementTextField() inside Column because it will stretch vertically
1

TextField itself is a Stateful widget, so when you call setState from inside the methods in TextField it will not update widgets outside of the text field.

To resolve this create the method in the parent widget to update the list and call setState from there, it will update the parent widget and the text field will be cleared.

Comments

1

You'll find the solution above this answer, this was just my approaches to fix the whole problem:

Trying to recreate a smaller version of my page, I found this issue:

@override
  Widget build(BuildContext context) {
   if (widget.data != null) {
      // editing set
      newSet.elements = widget.data['mySet']['elements'];
    } else {
      // creating set
      ...
    }

This was executed every time I added something to the array so I moved the check to initState().

Second error was this:

newSet.elements = widget.data['mySet']['elements'];

I had to modify this line and create my list without cloning it like so:

newSet.elements = []..addAll(widget.data['mySet']['elements']);

At this point, my list was adding more elements but it wasn't being displayed (I didn't mention this issue but I'll show the solution anyway).

I had this var containing some widgets:

_steps = [
      _step0(),
      _step1(),
      _step2(),
    ];

This list was being used to change dynamically a Swiper widget (more info).

So instead of doing this:

Swiper(
    itemBuilder: (BuildContext context, int index) {
       return _steps[index];
    },

I do this now:

    Swiper(
        itemBuilder: (BuildContext context, int index) {
              switch (index) {
                    case 1:
                      return _step1();
                      break;
                    case 2:
                      return _step2();
                      break;
                    default:
                      return _step0();
                  }
        },

1 Comment

the last change makes sense, as the widgets in the list are built only once when the list is built, but in switch case it builds every time the case is executed... awesome debugging, bro.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.