是 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();
}
},
)
请帮帮我。.
答案 0 :(得分:0)
inicialize:
TextEditingController controller;
在initState上:
@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