【问题标题】:Flutter: How to add a TextField or TextFormField programmaticallyFlutter:如何以编程方式添加 TextField 或 TextFormField
【发布时间】:2019-08-30 22:48:08
【问题描述】:

我已经创建了一个表单,其中 formkey 和表单数据变量为 Map<String, String> _formdata = {}; formdata 包含个人资料数据等字段。
其中有一个字段说宠物,它有两个字段名称和年龄。
我想添加一个按钮,允许用户添加更多宠物。此表单应仅在单击按钮时可见。用户可以通过点击这个按钮添加多个宠物。

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}

【问题讨论】:

  • 如果可以的话,能否添加完整的代码
  • 好的,我已经添加了完整的代码

标签: flutter dart flutter-layout


【解决方案1】:

让我知道它是否有效。

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}
  • 我一一创建并添加。让我换个方式测试一下。
  • 如果我填写数据然后添加另一个字段填充它并添加另一个,我能够实现您的答案。但如果一次添加多个字段则不起作用。如果进行了编辑,它也不起作用
  • 我也有同样的情况,添加TextInput 效果很好。但是,如果我们想从表单中删除TextInput,那么从技术上讲,它会减少索引值以及List&lt;Widget&gt; 中的Widget 项。但是 UI 没有得到更新?我
  • 我解决了从表单中删除添加的TextInput 的查询。这将与我们在List&lt;Widget&gt; 中添加Widget 的方式相同。 _myStudents = List.from(_myStudents)..removeAt(keyValue - 1);
【解决方案2】:

由于您没有共享任何代码,因此我将告诉您如何执行此操作。这是完整的代码。

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 我如何从文本字段中获取数据?
  • @Ggriffo 您可以将controller 分配给TextEditingController 并使用_children[0].controller.text 之类的东西来获取文本值。
  • @CopsOnRoad 如果我们想从这个列表中删除一些项目怎么办?我可以使用List.of(_data)..removeAt(position) 更新列表并删除特定位置项。但是如果我们删除它,我们的Map&lt;&gt; 数据项会发生什么?我无法做到这一点。
  • @PurvikRana 你能指导我如何在flutter-bloc状态管理中实现这一点。
猜你喜欢
  • 1970-01-01
  • 2020-02-02
  • 1970-01-01
  • 2015-05-01
  • 2016-11-23
  • 2012-09-16
  • 2014-07-03
  • 2016-04-02
  • 1970-01-01
相关资源
最近更新 更多