如何在 ExpansionTile Flutter 中使用动态 TextField 控制器

How to use dynamic TextField Controller inside ExpansionTile Flutter

作为 Flutter 的新手,我创建了一个 ExpansionTile(见下面的截图)并添加了 EditField 作为 Child.
这里 ExpansioTile 和评论 EditField 是根据服务器响应动态创建的。 每个ExpansionTile里面会有多个TextFields

现在如何动态添加 TextFieldController 并在单击按钮时获取所有值?

ExpansionTile 代码

FutureBuilder(
              future: _fetchQuestions(),
              builder: (context, AsyncSnapshot snapshot){
                if (snapshot.hasError) {
                  return Text('Error ${snapshot.error}');
                }
                else  if (snapshot.hasData) {
                  return new Padding(
                    padding: EdgeInsets.fromLTRB(20.0, 5.0, 20.0, 0.0),
                    child: Container(
                      child: PageView.builder(
                        physics: new NeverScrollableScrollPhysics(),
                        controller: _pageController,
                        itemCount: snapshot.data[0].auditAreas.length,
                        onPageChanged: (int index) {
                          print('@@ on page changed $index');
                        },
                        itemBuilder: (BuildContext context, int index) {
                          print('@@ index '+index.toString());

                          List<QuestionGroups> listQuestionsGrp = snapshot.data[0].auditAreas[index].questionGroups;
                          print('@@ question grp list size == '+listQuestionsGrp.length.toString());

                          List<Widget> list = new List<Widget>();
                          for (int i=0; i<listQuestionsGrp.length; i++){

                            bloc.newFields();
                            List<Widget> listItemWidgets = new List<Widget>();

                            // below list(listAuditQues) is used to get the questions from question groups
                            List<AuditQuestions> listAuditQues = listQuestionsGrp[i].auditQuestions;
                            for (int j=0; j<listAuditQues.length; j++){

                              print('@ audit question id == '+listAuditQues[j].auditQuestionId.toString());

                              // _mapController.map(listAuditQues[j].auditQuestionId, _textController);
                              // _controllers.add(TextEditingController());
                              List<AuditQuestionAnswers> listAuditQuestAns = listAuditQues[j].auditQuestionAnswers;
                              print('@@ list of question and answers used for radio buttons == '+listAuditQuestAns.length.toString());

                              List<Widget> listTitleOfRadioButtons = new List<Widget>();
                              for (int k=0; k<listAuditQuestAns.length; k++){

                                // here have to get the list of radio button text and append below inside the column
                                List<AuditQuestionAnswerOptionParameters> listQuesAnsParameter = listAuditQuestAns[k].auditQuestionAnswerOptionParameters;
                                print('@@ list question answer list size == '+listQuesAnsParameter.length.toString());
                                List<Widget> listRadioButtons = new List<Widget>();

                                for (int m=0; m<listQuesAnsParameter.length; m++){
                                  listRadioButtons.add(
                                      Row(
                                        mainAxisAlignment: MainAxisAlignment.start,
                                        children: <Widget>[
                                          new Radio(value: 0, groupValue: null, onChanged: null, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,),
                                          new Text(listQuesAnsParameter[m].answerOptionParameterTitle,style: TextStyle(
                                              fontSize: 12.0
                                          ))
                                        ],
                                      )
                                  );
                                }

                                listTitleOfRadioButtons.add(
                                  Column(
                                    children: <Widget>[
                                      Align(
                                        alignment: Alignment.centerLeft,
                                        child: Container(
                                          margin: EdgeInsets.fromLTRB(10.0, 4.0, 0.0, 4.0),
                                          child: Text(listAuditQuestAns[k].auditEntityTitle,
                                          style: TextStyle(fontSize: 13.5),),
                                        ),
                                      ),
                                      Row(
                                        children: listRadioButtons,
                                      )
                                    ],
                                  )
                                );
                              }

                              // Here adding expansion item content
                              listItemWidgets.add(
                                  Column(
                                    children: <Widget>[
                                      Row(
                                        // mainAxisAlignment: message.author == username ? MainAxisAlignment.end : MainAxisAlignment.start,
                                        //this will determine if the message should be displayed left or right
                                          children: [
                                            Flexible(
                                              //Wrapping the container with flexible widget
                                              child: Container(
                                                  padding: EdgeInsets.all(6.0),
                                                  margin: EdgeInsets.all(4.0),
                                                  decoration: BoxDecoration(
                                                      borderRadius: BorderRadius.circular(4.0),
                                                      border: Border.all(color: Colors.black)
                                                  ),
                                                  child: Row(
                                                    children: <Widget>[
                                                      Flexible(
                                                        //We only want to wrap the text message with flexible widget
                                                          child: Container(
                                                              child: Text(
                                                                listAuditQues[j].title,
                                                              )
                                                          )
                                                      ),
                                                    ],
                                                  )
                                              ),
                                            )

                                          ]
                                      ),

                                      Column(
                                        children: listTitleOfRadioButtons
                                      ),

                                      Container(
                                        height: 80,
                                        margin: EdgeInsets.all(4.0),
                                        child: new ConstrainedBox(
                                          constraints: BoxConstraints(
                                            maxHeight: 80.0,
                                          ),
                                          child: new Scrollbar(
                                            child: new SingleChildScrollView(
                                              scrollDirection: Axis.vertical,
                                              reverse: true,
                                              child: SizedBox(
                                                height: 80.0,
                                                child: new TextFormField(
                                                 // controller: _controllers[j],
                                                  maxLines: 60,
                                                  decoration: new InputDecoration(
                                                    labelText: "Comment",
                                                    focusedBorder: OutlineInputBorder(
                                                        borderSide:
                                                        BorderSide(color: Colors.black, width: 0.8)),
                                                    enabledBorder: OutlineInputBorder(
                                                        borderSide:
                                                        BorderSide(color: Colors.black, width: 0.8)),
                                                  ),
                                                ),
                                              ),
                                            ),
                                          ),
                                        ),
                                      ),
                                      new Container(
                                        margin: EdgeInsets.all(4.0),
                                        padding: EdgeInsets.fromLTRB(2.0, 4.0, 0.0, 0.0),
                                        child: new Row(
                                          mainAxisAlignment: MainAxisAlignment.start,
                                          children: <Widget>[
                                            GestureDetector(
                                              onTap: (){
                                                print('@@ index of pager $index');
                                                print('@@ index of main lopp $i');
                                                print('@@ index of lopp $j');
                                              },
                                              child: new Icon(Icons.camera_alt,
                                                  size: 22.0, color: Colors.black),
                                            ),
                                            new Icon(Icons.attach_file,
                                                size: 22.0, color: Colors.black),
                                            new Text("(4)", style: TextStyle(fontSize: 12.0))
                                          ],
                                        ),
                                      ),

                                      Container(
                                        margin: EdgeInsets.all(4.0),
                                        child: Divider(height: 4.0,color: Colors.black),
                                      )
                                    ],
                                  )
                              );
                            }

                            // Main Title of expansion list adding here
                            list.add(customExpansionTile.ExpansionTile(
                                headerBackgroundColor: Colors.grey,
                                backgroundColor: Colors.white,
                                iconColor: Colors.black,
                                title: Text(listQuestionsGrp[i].title, style: TextStyle(
                                  fontSize: 14.0
                                )),
                              children: listItemWidgets
                            ));

                          }
                          return new ListView(
                            children: list,
                          );

                          // return _buidlExpnsionListTile(snapshot.data[0]);
                           /*List<AuditAreas> auditAreaList = snapshot.data[index].auditAreas;
                           print('@@ audit area list size == ${auditAreaList.length}');
                          return Text('Screen index == '+index.toString());*/
                        },
                      ),
                    ),
                  );
                }
                else{
                  return CircularProgressIndicator();
                }
              },
            )

请帮帮我..

初始化它:

TextEditingController controller;

在初始状态:

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

    controller = new TextEditingController();
  }

TextFormField 中的控制器示例:

new TextFormField(
                validator: (senha) =>
                    senha.isEmpty ? 'Por favor insira sua senha' : null,
                onSaved: (senha) => _pass = senha,
                obscureText: true,
                textAlign: TextAlign.start,
                decoration: InputDecoration(
                  prefixIcon: Icon(
                    Icons.vpn_key,
                  ),
                  border: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(10.0)),
                  filled: true,
                  hintText: 'Senha',
                ),
                controller: controller,
              ),

要访问 TextFormField 文本,只需 controller.text