每次我按下删除按钮时,它都会删除最后一项
Every time i press remove button it removes the last item
当按下加号按钮时,新的 From 被添加到屏幕上,并且每个表单都有自己的删除按钮,调用 removeUserForm 函数形成 HomePageState class。但问题是,当按下每个删除按钮时,它会删除最后一项,但正如我所料,应该删除拥有删除按钮的表单。
为什么会这样?
我在 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"),),
],
),
),
);
}
}
首先,您可以像这样使用包裹在 SingleChildScrollView 中的 Column。我认为在这里使用 ListView.builder 小部件实现是个坏主意
child: SingleChildScrollView(
child: Column(
children: _userForms,
),
),
接下来,您必须向您的用户窗体小部件添加一个密钥,并为您添加的所有表单设置一个唯一的密钥(例如增量)。 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"),
),
当按下加号按钮时,新的 From 被添加到屏幕上,并且每个表单都有自己的删除按钮,调用 removeUserForm 函数形成 HomePageState class。但问题是,当按下每个删除按钮时,它会删除最后一项,但正如我所料,应该删除拥有删除按钮的表单。 为什么会这样?
我在 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"),),
],
),
),
);
}
}
首先,您可以像这样使用包裹在 SingleChildScrollView 中的 Column。我认为在这里使用 ListView.builder 小部件实现是个坏主意
child: SingleChildScrollView(
child: Column(
children: _userForms,
),
),
接下来,您必须向您的用户窗体小部件添加一个密钥,并为您添加的所有表单设置一个唯一的密钥(例如增量)。 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"),
),