Flutter: добавлен дополнительный TextFormField в столбец, но без изменений в отображении - PullRequest
0 голосов
/ 28 апреля 2020

Я делаю Форму, которая принимает таблицу как своего ребенка. Есть кнопка для добавления дополнительного столбца и еще одна кнопка для добавления дополнительного TextFormField. Кнопки реализованы в _MyHomePageState.

Итак, настройка аналогична приведенной ниже ссылке.

https://flutter.dev/docs/development/ui/interactive#the -parent-widget-manages-the-widgets-state

Когда вызывается метод addTextFormField, в List _textFormFields добавляется новый TextFormField. Список _columns принимает _textFormFields в качестве дочерних элементов. Следовательно, _columns также изменяется. Затем _columns передается конструктору FormA через сборку.

На данный момент в _columns есть 1 виджет столбца и 2 виджета TextFormFields в виджете столбца. Тем не менее, он отображает только 1 TextFormField.

Затем, когда я нажимаю кнопку addColumn, появляется дополнительный столбец с двумя полями TextForm.

Почему при нажатии addTextFormField нет 2 TextFormFields?

main.dart

    class _MyHomePageState extends State<MyHomePage> {

      List<Widget> _columns;
      List<Widget> _textFormFields;

      @override
      void initState(){
        super.initState();
          _columns = List<Widget>();
          _textFormFields = List<Widget>();

          _addTextFormField();
          _addColumn();
      }

      void _addTextFormField() async {
          _textFormFields.add(TextFormField(
                        decoration: InputDecoration(
                        hintText: _textFormFields.length.toString()),
                        ),
                      );

          for(Column column in _columns){
            print('from _addTextFormField ' + column.children.length.toString()); 
           // press addTextFormField button once, it prints  2

            print('from _addTextFormField ' + column.children.toString()); 
           //press addTextFormField button once, it prints [TextFormField, TextFormField]
          }

          setState((){

          });
      }

      void _addColumn() async {

          print('from addColumn   no. of textFormFields ' + _textFormFields.length.toString());
          _columns.add(Column(
                      children: _textFormFields,),
                      );

          for(Column column in _columns){
            print('from addColumn   no. of widget in a column ' + column.children.length.toString());
          }

          setState((){
          });
      }

      @override
      Widget build(BuildContext context) {

        print('rebuild');
        // press addTextFormField button once, it prints rebuild
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                FormA (columns : _columns),
              ],
            ),
          ),

          floatingActionButton: Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: <Widget>[
                FloatingActionButton(
                  onPressed: _addColumn,
                  tooltip: '+C',
                  child: Icon(Icons.add),
                ),
                FloatingActionButton(
                  onPressed: _addTextFormField,
                  tooltip: '+R',
                  child: Icon(Icons.add),
                ),
            ],
          ),


        );
      }
    }

formA.dart

class FormA extends StatelessWidget{

  FormA({Key key, this.columns})
      : super(key: key);

  List<Widget> columns;

  @override
  Widget build(BuildContext context) {

      for(Column column in columns){
        print('from FormA   no. of widget in a column ' + column.children.length.toString());
       // press addTextFormField button once, it prints 2
        print('from FormA ' + column.children.toString());
       // press addTextFormField button once, it prints [TextFormField, TextFormField]
      }

    return Form(
      child: Table(
        children: [TableRow(
          children: columns,
        ),],
      ),
    );
  }
}

Ответы [ 2 ]

1 голос
/ 28 апреля 2020

Ваш код в его текущей форме не будет работать так, как вы ожидаете, поскольку список _columns, хотя и имеет ссылку на _textFormFields, изначально созданный вами виджет Column уже создал children и не изменится если вы измените его MyhomePage виджет, потому что у него не будет ссылки.

В его текущей форме ваш код работает следующим образом. enter image description here

Все, что вам нужно сделать, - это переназначить поле _columns в методе setState из _addTextFormField, который перестроит весь список столбцов, как этот.


void _addTextFormField() {
    _textFormFields.add(
      TextFormField(
        decoration:
            InputDecoration(hintText: _textFormFields.length.toString()),
      ),
    );

    for (Column column in _columns) {
      print('from _addTextFormField ' + column.children.length.toString());
      // press addTextFormField button once, it prints  2

      print('from _addTextFormField ' + column.children.toString());
      //press addTextFormField button once, it prints [TextFormField, TextFormField]

    }

    setState(() {
      _columns = List<Column>.generate(
          _columns.length, (index) => Column(children: _textFormFields));
    });
  }

После этого изменения оно будет выглядеть следующим образом.

enter image description here

Вот ручка с живым кодом с решением.

https://codepen.io/abhilas-csc/pen/dyYRVrL

0 голосов
/ 28 апреля 2020

Затем, когда я нажимаю кнопку addColumn, появляется дополнительный столбец с двумя TextFormFields.

Почему при нажатии addTextFormField нет 2 TextFormFields?

Не совсем ! Когда виджет инициализируется, у вас есть ровно один Column и ровно один TextFormField в каждом списке. Теперь вы нажимаете addColumn, поэтому добавляется еще один Column. Итак, у вас есть два Column с, но все же один TextFormField.

Надеюсь, это поможет.

...