Flutter:如何以编程方式添加TextField或TextFormField

9

我已经创建了一个带有表单键和表单数据变量的表单,例如Map<String, String> _formdata = {}; formdata包含配置文件数据等字段。
其中有一个字段称为Pets,它有两个字段名称和年龄。
我想添加一个按钮,允许用户添加更多的宠物。这个表格只有在点击按钮时才会显示。用户可以通过单击此按钮添加多个宠物。

class MyPets extends StatefulWidget {
  @override
  _MyPetsState createState() => _MyPetsState();
}

class _MyPetsState extends State<MyPets> {
  Map<String, String> _formdata = {};
  var _myPets = List<Widget>();
  int _index = 1;

  void _add() {
    _myPets = List.from(_myPets)
      ..add(Column(
        children: <Widget>[
          ListTile(
            leading: Text('Pet $_index : '),
            title: TextField(
              onChanged: (val) => _formdata['pet$_index'] = val,
            ),
          ),
          ListTile(
            leading: Text('Name of Pet $_index : '),
            title: TextField(
              onChanged: (val) {
                _formdata['name$_index'] = val;

              },
            ),
          ),
        ],
      ));

    setState(() => ++_index);
  }
@override
  void initState() {
    // TODO: implement initState
    super.initState();
    _add();
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: ()=>print(_formdata),
        child: Text('Save'),
      ),
      appBar: AppBar(
        title: Text('Add your pets'),
        actions: <Widget>[
          FlatButton(
            child: Text('Add another'),
            onPressed: _add,
          ),
        ],
      ),
      body: ListView(
        children: _myPets,
      ),
    );
  }
}

问题在于当我打印_formdata时,我只得到了最后一个值。

{pet6: 5, name6: 5} 这里输入图片描述


如果可能的话,您能否添加完整的代码? - Mangaldeep Pannu
好的,我已经添加了完整的代码。 - CodeforCore
2个回答

6

如果它能正常工作,请告诉我。

class MyPets extends StatefulWidget {
  @override
  _MyPetsState createState() => _MyPetsState();
}

class _MyPetsState extends State<MyPets> {
  Map<String, String> _formdata = {};
  var _myPets = List<Widget>();
  int _index = 1;

  void _add() {
    int keyValue = _index;
    _myPets = List.from(_myPets)
      ..add(Column(
        key: Key("${keyValue}"),
        children: <Widget>[
          ListTile(
            leading: Text('Pet $_index : '),
            title: TextField(
              onChanged: (val) => _formdata['pet${keyValue - 1}'] = val,
            ),
          ),
          ListTile(
            leading: Text('Name of Pet $_index : '),
            title: TextField(
              onChanged: (val) {
                _formdata['name${keyValue - 1}'] = val;
              },
            ),
          ),
        ],
      ));

    setState(() => ++_index);
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _add();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: () => print(_formdata),
        child: Text('Save'),
      ),
      appBar: AppBar(
        title: Text('Add your pets'),
        actions: <Widget>[
          FlatButton(
            child: Text('Add another'),
            onPressed: _add,
          ),
        ],
      ),
      body: ListView(
        children: _myPets,
      ),
    );
  }
}

很遗憾,这对我没有起作用。首先,我点击了“添加”几次以创建多个字段,然后添加了数据,但只得到了最后一个条目的输出{pet2: 2, name2: b}。此外,当我编辑第一个时,输出仍然反映了最后一次更改{pet2: edit 1, name2: b} - CodeforCore
1
我逐个创建并添加。让我以另一种方式进行测试。 - CopsOnRoad
如果我填写数据,然后添加另一个字段并填写它,再添加另一个字段,我就能得到您的答案。但是如果一次添加多个字段,则无法正常工作。如果进行编辑也不起作用。 - CodeforCore
我也遇到了同样的问题,添加TextInput时它能正常工作。但是如果我们想从表单中删除TextInput,那么技术上它会减少索引值以及从List<Widget>中移除Widget项。但是UI没有得到更新? - Purvik Rana
2
我解决了从表单中删除添加的 TextInput 的问题。这将以与我们向 List<Widget> 中添加 Widget 相同的方式完成。 _myStudents = List.from(_myStudents)..removeAt(keyValue - 1); - Purvik Rana

5

enter image description here

由于您没有分享任何代码,我将为您提供一个想法,告诉您如何实现它。这是完整的代码。

List<Widget> _children = [];
int _count = 0;

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text("Title"),
      actions: <Widget>[IconButton(icon: Icon(Icons.add), onPressed: _add)],
    ),
    body: ListView(children: _children),
  );
}

void _add() {
  _children = List.from(_children)
    ..add(TextFormField(
      decoration: InputDecoration(hintText: "This is TextField ${_count}"),
    ));
  setState(() => ++_count);
}

@CopsOnRoad 我怎样从文本框中获取数据? - griffins
3
你可以将controller赋值为一个TextEditingController对象,然后使用类似_children[0].controller.text的语句来获取文本的值。 - CopsOnRoad
@CopsOnRoad 如果我们想从这个列表中删除一些项目怎么办?我可以使用 List.of(_data)..removeAt(position) 更新列表并删除特定位置的项目。但是,如果我们将其删除,我们的 Map<> 数据项会发生什么?我无法实现这一点。 - Purvik Rana
@PurvikRana,你能指导我如何在Flutter-Bloc状态管理中实现这个吗? - Aravinthan Subramanian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接