简体   繁体   English

Flutter:向 Column 添加了一个额外的 TextFormField 但显示没有变化

[英]Flutter: Added an additional TextFormField to Column but no change in display

I am making a Form which takes a table as its child.我正在制作一个表格,它以表格为子。 There is a button to add additional Column and another button to add additional TextFormField.有一个按钮可以添加额外的 Column,另一个按钮可以添加额外的 TextFormField。 The buttons are implemented the _MyHomePageState.按钮实现为 _MyHomePageState。

So, the setup is like the one in the link below.因此,设置类似于下面链接中的设置。

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

When the addTextFormField method is invoked, a new TextFormField is added to List _textFormFields.调用 addTextFormField 方法时,会将一个新的 TextFormField 添加到 List _textFormFields。 The List _columns takes _textFormFields as children. List _columns 将 _textFormFields 作为子项。 Therefore, _columns is also changed.因此,_columns 也发生了变化。 _columns is then passed to FormA constructor through build. _columns 然后通过 build 传递给 FormA 构造函数。

At this moment, there is 1 Column Widget in _columns and 2 TextFormFields in the Column Widget.此时,_columns 中有 1 个 Column Widget,Column Widget 中有 2 个 TextFormFields。 However, it only displays 1 TextFormField.但是,它只显示 1 个 TextFormField。

Then when I press addColumn button, an additional Column with two TextFormFields will appear.然后当我按下 addColumn 按钮时,将出现一个带有两个 TextFormFields 的附加列。

Why there are not 2 TextFormFields when I press addTextFormField?为什么按 addTextFormField 时没有 2 个 TextFormField?

main.dart 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表格A.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,
        ),],
      ),
    );
  }
}

You code in its current form will not work as you expect because the _columns list even though has the reference to _textFormFields , the Column widget you initially built has its children already built and will not change if you change it MyhomePage widget because it will not have its reference.您以其当前形式编写的代码将无法按预期工作,因为_columns列表即使具有对_textFormFields的引用,您最初构建的Column小部件已经构建了其children级,并且如果您更改它MyhomePage小部件也不会更改,因为它不会其参考。

In its current form you code works like this.在当前的形式中,你的代码是这样工作的。 在此处输入图像描述

All you need to do is reassign the _columns field in the setState of _addTextFormField method which will rebuild the whole list of columns like this.您需要做的就是在_addTextFormField方法的setState中重新分配_columns字段,该方法将像这样重建整个列列表。


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));
    });
  }

After this change it will look like this.在此更改后,它将如下所示。

在此处输入图像描述

Here is a live code pen with the solution.这是带有解决方案的实时代码笔。

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

Then when I press addColumn button, an additional Column with two TextFormFields will appear.然后当我按下 addColumn 按钮时,将出现一个带有两个 TextFormFields 的附加列。

Why there are not 2 TextFormFields when I press addTextFormField?为什么按 addTextFormField 时没有 2 个 TextFormField?

Not really, When the widget initializes, you have exactly one Column and exactly one TextFormField in each List.并非如此,当小部件初始化时,每个列表中只有一个Column和一个TextFormField Now you press addColumn so one more Column is added.现在您按下addColumn ,这样又添加了一个Column So you have two Column s but still one TextFormField .因此,您有两个Column ,但仍然有一个TextFormField

I hope that helps.我希望这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何更改 TextFormField() 小部件颜色 Flutter - How to change TextFormField() widget color Flutter 仅当专注于颤动时如何在 TextFormField() 上显示计数器文本? - How to display counter text on TextFormField() only when focused in flutter? 在 Flutter 中,如何更改 TextFormField 验证错误行样式? - In Flutter, How can I change TextFormField validation error line style? Flutter 中不推荐使用 TextFormField 的自动验证 - Autovalidate of TextFormField is deprecated in Flutter Flutter Textformfield 验证器将最后一个 TextFormfield 集中在验证错误上,而不是第一个 - Flutter Textformfield validator Focuses Last TextFormfield on validation error instead of first Flutter-在TextTextField上显示对话框编号选择器 - Flutter - Show Dialog NumberPicker on Tap TextFormField 表单的 TextFormField 中的多个光标抖动 - Multiple cursor in form's TextFormField flutter 在 listview flutter 内的 textformfield 中按下数字后键盘关闭 - keyboard close after pressing a number in textformfield inside listview flutter 在Flutter TextFormField中输入数据时,键盘不断消失 - Keyboard keeps disappearing while entering data in Flutter TextFormField 为什么 Flutter 会重新渲染包含带有自己的键的 TextFormField 的小部件? - Why Flutter rerenders widget which contains a TextFormField with own key?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM