首页 > 解决方案 > 将小部件 (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()
        )
      )
    );
  }
}

标签: flutterflutter-form-builder

解决方案


您可以在下面复制粘贴运行完整代码
您需要提供不同的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(),
    );
  }
}

推荐阅读