Каждый раз, когда я нажимаю кнопку удаления, он удаляет последний элемент - PullRequest
0 голосов
/ 26 марта 2020

Когда нажата кнопка «плюс», на экран добавляется новый From, и каждая форма имеет собственную кнопку удаления, вызывающую класс функции HomePageState формы removeUserForm . но проблема в том, что при каждом нажатии кнопки удаления он удаляет последний элемент, но, как я и ожидал, должна быть удалена только форма, принадлежащая кнопке удаления. почему это произошло?

я загрузил полный код в Github: https://github.com/geek-sajjad/dynamic_form

class _MyHomePageState extends State<MyHomePage> {

 List<UserForm> _userForms = <UserForm>[];

  void removeUserForm(User user){
    var find =_userForms.firstWhere((userForm) => userForm.user == user);
    if(find!=null){
      _userForms.removeAt(_userForms.indexOf(find));
    }
    setState(() {

    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _userForms.add(UserForm(              
              onRemoved: removeUserForm,
              user: User(),
            ));
          });
        },
        child: Icon(Icons.add),
      ),
      body: SafeArea(
        child: ListView.builder(
          padding: EdgeInsets.all(15),
          itemBuilder: (ctx, int index) {
            return _userForms[index];
          },
          itemCount: _userForms.length,
        ),
      ),
    );
  }
}



class UserForm extends StatelessWidget {
  final User user;
  final Function onRemoved;
  UserForm({this.user, this.onRemoved, });  
  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 6,
      margin: EdgeInsets.all(10),
      child: Padding(
        padding: EdgeInsets.all(15),
              child: Column(
          children: <Widget>[
            TextField(
              onChanged: (value){
                this.user.email = value;
              },
              decoration: InputDecoration(
                labelText: "Email",
                border: OutlineInputBorder(),

              ),
            ),
            SizedBox(height: 20,),
            TextField(
              onChanged: (value){
                this.user.name = value;
              },
              decoration: InputDecoration(
                labelText: "Name",
                border: OutlineInputBorder(),
              ),
            ),
            SizedBox(height: 10,),
            RaisedButton(onPressed: (){              
              this.onRemoved(this.user);
            }, child: Text("Remove"),),
          ],
        ),
      ),
    );
  }

}

1 Ответ

1 голос
/ 27 марта 2020

Во-первых, вы можете использовать столбец, завернутый в SingleChildScrollView, как это. Я думаю, что это плохая идея использовать здесь реализацию виджета ListView.builder

child: SingleChildScrollView(
  child: Column(
    children: _userForms,
  ),
),

Далее необходимо добавить ключ к виджету UserForm и установить уникальный ключ для всех добавляемых форм (приращение для пример). Flutter нужен этот ключ, чтобы знать, какой виджет (пере) рисует.

_userForms.add(UserForm(
  key: Key('$uniqueFormIndex'),
  onRemoved: removeUserForm,
  user: User(),
));

Наконец, вы можете упростить ваш метод удаления, передав саму форму.

void removeUserForm(UserForm userForm) {
setState(() {
  _userForms.remove(userForm);
});

Изменить конструктор Ваш UserForn wiget

UserForm({
  Key key,
  this.user,
  this.onRemoved,
}) : super(key: key);

И измените onRemoved

RaisedButton(
  onPressed: () {
    this.onRemoved(this);
  },
  child: Text("Remove"),
),
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...