问题
I have created a form in with formkey and and form data variable as Map<String, String> _formdata = {};
formdata contains field such as profile data.
Among those there is a field say Pets, It has two fields name and age.
I want to add a button that will allow user to add more pets. This form should be visible only when clicking the button. User can add multiple pets by clicking this button.
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,
),
);
}
}
The problem is when I print _formdata, I am only getting last value.
{pet6: 5, name6: 5}
回答1:
Let me know if it works.
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,
),
);
}
}
回答2:
Since you didn't share any code, I am giving you an idea how you can do it. Here is the complete code.
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);
}
来源:https://stackoverflow.com/questions/55596251/flutter-how-to-add-a-textfield-or-textformfield-programmatically