Flutter: как программно добавить TextField или TextFormField

Я создал форму с помощью 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, я получаю только последнее значение.

{пет6: 5, имя6: 5} Flutter: как программно добавить TextField или TextFormField

Можете ли вы добавить полный код, если это возможно

Mangaldeep Pannu 09.04.2019 18:31

Хорошо, я добавил полный код

CodeforCore 09.04.2019 19:04
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
2
6 747
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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, как мне получить данные из текстовых полей?

griffins 29.10.2019 04:02

@Ggriffo Вы можете назначить controllerTextEditingController и использовать что-то вроде _children[0].controller.text для получения текстового значения.

CopsOnRoad 29.10.2019 05:19

@CopsOnRoad Что делать, если мы хотим удалить некоторые элементы из этого списка? Я могу обновить список, используя List.of(_data)..removeAt(position), и удалить определенный элемент позиции. Но что произойдет с нашими Map<> элементами данных, если мы их удалим? Я не мог этого добиться.

Purvik Rana 11.02.2020 12:27

@PurvikRana, не могли бы вы рассказать мне, как добиться этого в управлении состоянием флаттер-блока.

Aravinthan Subramanian 12.10.2021 03:50
Ответ принят как подходящий

Дайте мне знать, если это работает.

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} <br> Также, когда я редактирую первую запись, вывод по-прежнему отражает последнее изменение {pet2: edit 1, name2: b}

CodeforCore 09.04.2019 19:26

Я создал и добавил один за другим. Позвольте мне проверить это по-другому.

CopsOnRoad 09.04.2019 19:28

Я могу получить ваш ответ, если я заполню данные, затем добавлю еще одно поле, заполню его и добавлю другое. Но не работает, если несколько полей добавлены одновременно. Это также не работает, если внесены правки

CodeforCore 09.04.2019 19:31

У меня было то же самое, и для добавления TextInput это работает хорошо. Но что, если мы хотим удалить TextInput из формы, то технически это уменьшает значение индекса, а также элемент Widget из List<Widget>. Но интерфейс не обновляется? я

Purvik Rana 11.02.2020 07:36

Я решил свой запрос на удаление добавленного TextInput из формы. Это будет сделано так же, как мы добавляем Widget в List<Widget>. _myStudents = List.from(_myStudents)..removeAt(keyValue - 1);

Purvik Rana 11.02.2020 08:15

Другие вопросы по теме