flutter - 将小部件 (FormBuilderTextField) 动态添加到 formBuilder
问题描述
我正在使用 flutter_form_builder 创建我的表单。用户将使用表单创建自己的投票,并且他/她将根据需要向他/她的问题添加选项。我解决了选择部分的动态添加,但现在的问题是;当我用一个选项创建一个问题并点击提交按钮时,选择、问题和日期会打印在控制台中,但是如果我点击 fab 按钮来创建另一个选择,只有新创建的字段会打印它的内容日期和问题,旧字段被忽略。
如何获得动态创建的每个字段的结果..
提前致谢..
这是我的代码:-
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:intl/intl.dart';
class AddPoll extends StatefulWidget {
@override
_AddPollState createState() => _AddPollState();
}
class _AddPollState extends State<AddPoll> {
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
List<Widget> choiceFieldList;
void initState() {
super.initState();
choiceFieldList = <Widget>[];
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(title: Text("Create a poll")),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
setState(() {
choiceFieldList.add(ChoiceField());
});
}
),
body: Padding(
padding: EdgeInsets.all(10.0),
child: SingleChildScrollView(
child: Column(
children: [
FormBuilder(
key: _fbKey,
initialValue: {
'date': DateTime.now()
},
autovalidateMode: AutovalidateMode.always,
child: Column(
children: <Widget>[
FormBuilderTextField(
attribute: 'question',
validators: [FormBuilderValidators.required()],
maxLines: null,
keyboardType: TextInputType.multiline,
decoration: InputDecoration(
labelText: "Your Question",
border: OutlineInputBorder()
)
),
Container(
padding: EdgeInsets.fromLTRB(0, 30, 0, 20),
alignment: Alignment.centerLeft,
child: Text(
"Choices:-",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold
)
)
),
ListView.builder(
shrinkWrap: true,
itemCount: choiceFieldList.length,
itemBuilder: (context, index) => choiceFieldList[index],
),
Visibility(
visible: false,
child: FormBuilderDateTimePicker(
attribute: "date",
inputType: InputType.both,
validators: [FormBuilderValidators.required()],
format: DateFormat("dd-MM-yyyy 'at' h:mma"),
decoration: InputDecoration(labelText: "Date of Poll")
)
)
]
)
),
SizedBox(height: 30.0),
ButtonBar(
alignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
child: Text("Reset"),
onPressed: () {
_fbKey.currentState.reset();
}
),
RaisedButton(
child: Text("Submit"),
onPressed: () async {
_fbKey.currentState.save();
print(_fbKey.currentState.value);
if (_fbKey.currentState.validate()) {
// Loading().show(context);
// var date = _fbKey.currentState.value['date'];
// var resp = await registerUser(date);
}
}
)
]
)
]
)
)
)
)
);
}
}
class ChoiceField extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: FormBuilderTextField(
attribute: 'choice',
validators: [FormBuilderValidators.required()],
decoration: InputDecoration(
labelText: "Enter Choice",
border: OutlineInputBorder()
)
)
);
}
}
解决方案
您可以在下面复制粘贴运行完整代码
您需要提供不同的attribute
名称
,您可以使用attributeName: "choice ${choiceFieldList.length}"
代码片段
onPressed: () {
setState(() {
choiceFieldList.add(ChoiceField(
attributeName: "choice ${choiceFieldList.length}",
));
});
}
...
class ChoiceField extends StatelessWidget {
final String attributeName;
ChoiceField({this.attributeName});
@override
Widget build(BuildContext context) {
return Center(
child: FormBuilderTextField(
attribute: attributeName,
输出
I/flutter ( 7497): {date: 2020-10-05 08:54:56.785373, question: q, choice 0: a, choice 1: b}
工作演示
完整代码
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:intl/intl.dart';
class AddPoll extends StatefulWidget {
@override
_AddPollState createState() => _AddPollState();
}
class _AddPollState extends State<AddPoll> {
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
List<Widget> choiceFieldList;
void initState() {
super.initState();
choiceFieldList = <Widget>[];
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(title: Text("Create a poll")),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
setState(() {
choiceFieldList.add(ChoiceField(
attributeName: "choice ${choiceFieldList.length}",
));
});
}),
body: Padding(
padding: EdgeInsets.all(10.0),
child: SingleChildScrollView(
child: Column(children: [
FormBuilder(
key: _fbKey,
initialValue: {'date': DateTime.now()},
autovalidateMode: AutovalidateMode.always,
child: Column(children: <Widget>[
FormBuilderTextField(
attribute: 'question',
validators: [FormBuilderValidators.required()],
maxLines: null,
keyboardType: TextInputType.multiline,
decoration: InputDecoration(
labelText: "Your Question",
border: OutlineInputBorder())),
Container(
padding: EdgeInsets.fromLTRB(0, 30, 0, 20),
alignment: Alignment.centerLeft,
child: Text("Choices:-",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold))),
ListView.builder(
shrinkWrap: true,
itemCount: choiceFieldList.length,
itemBuilder: (context, index) =>
choiceFieldList[index],
),
Visibility(
visible: false,
child: FormBuilderDateTimePicker(
attribute: "date",
inputType: InputType.both,
validators: [FormBuilderValidators.required()],
format: DateFormat("dd-MM-yyyy 'at' h:mma"),
decoration:
InputDecoration(labelText: "Date of Poll")))
])),
SizedBox(height: 30.0),
ButtonBar(
alignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
child: Text("Reset"),
onPressed: () {
_fbKey.currentState.reset();
}),
RaisedButton(
child: Text("Submit"),
onPressed: () async {
_fbKey.currentState.save();
print(_fbKey.currentState.value);
if (_fbKey.currentState.validate()) {
// Loading().show(context);
// var date = _fbKey.currentState.value['date'];
// var resp = await registerUser(date);
}
})
])
])))));
}
}
class ChoiceField extends StatelessWidget {
final String attributeName;
ChoiceField({this.attributeName});
@override
Widget build(BuildContext context) {
return Center(
child: FormBuilderTextField(
attribute: attributeName,
validators: [FormBuilderValidators.required()],
decoration: InputDecoration(
labelText: "Enter Choice", border: OutlineInputBorder())));
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: AddPoll(),
);
}
}
推荐阅读
- android - 这段代码与 xml 文件有什么问题?
- algorithm - 是什么让 prim 的算法避免了 CSLR 书中代码中的循环?
- javascript - Vuelidate isUnique 导致无限循环
- javascript - JS,字典列表到列表字典,基于键
- android - ImageSpan 在某些 API 级别中在图像上方添加空间
- android - 找不到“kotlinPlugin”和“darkThemeColors”
- c# - 如何计算 bpm(每分钟的心跳次数)?
- python - 如果数据框第 1 列中的数字是 x 并且如果第 2 列是 y 返回结果
- javascript - 在js中过滤json结果
- python - 按分组从数据框中选择行并在给定列中选择最大值