如何使用flutter_form_builder和ListView获取对象数组?
使用flutter_form_builder和ListView实现对象数组表单并获取指定结构数据
要实现你需要的{items: [{id: xx, name: xxxx}]}结构数据,你原来的代码存在几个关键问题:
- 每个输入框的
name没有区分列表项索引,提交时会出现数据覆盖,无法形成数组结构 - 错误使用了
FormFieldBuilder,flutter_form_builder的字段组件不需要额外包裹这个组件 - 没有利用flutter_form_builder的路径式name自动组织数组的特性
下面是修正后的完整实现方案:
核心思路
通过给每个列表项的输入框设置带索引的路径式name(比如'items[$index].id'),让flutter_form_builder自动将表单数据组织成你需要的数组结构。
完整代码示例
class ItemForm extends StatefulWidget { const ItemForm({super.key}); @override State<ItemForm> createState() => _ItemFormState(); } class _ItemFormState extends State<ItemForm> { final _formKey = GlobalKey<FormBuilderState>(); // 初始化空的列表项,也可以根据业务需求从外部传入初始数据 List<Map<String, dynamic>> items = [{'id': '', 'name': ''}]; // 添加新的列表项 void _addItem() { setState(() { items.add({'id': '', 'name': ''}); }); } // 删除指定索引的列表项 void _removeItem(int index) { setState(() { items.removeAt(index); }); } // 提交表单并获取目标结构数据 void _submitForm() { if (_formKey.currentState?.saveAndValidate() ?? false) { final formData = _formKey.currentState!.value; // formData就是你需要的{items: [{id: xx, name: xxxx}]}结构 print(formData); // 这里可以处理提交逻辑,比如发送到后端 } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('对象数组表单')), body: Padding( padding: const EdgeInsets.all(16.0), child: FormBuilder( key: _formKey, child: Column( children: [ Expanded( child: ListView.builder( shrinkWrap: true, itemCount: items.length, itemBuilder: (context, index) { return Card( margin: const EdgeInsets.symmetric(vertical: 8), child: Padding( padding: const EdgeInsets.all(8.0), child: Row( children: [ Expanded( child: FormBuilderTextField( name: 'items[$index].id', decoration: const InputDecoration(labelText: 'ID'), initialValue: items[index]['id'], ), ), const SizedBox(width: 16), Expanded( child: FormBuilderTextField( name: 'items[$index].name', decoration: const InputDecoration(labelText: '名称'), initialValue: items[index]['name'], ), ), IconButton( icon: const Icon(Icons.delete), onPressed: () => _removeItem(index), ), ], ), ), ); }, ), ), ElevatedButton( onPressed: _addItem, child: const Text('添加新项'), ), const SizedBox(height: 16), ElevatedButton( onPressed: _submitForm, child: const Text('提交表单'), ), ], ), ), ), ); } }
关键说明
- 路径式name:
'items[$index].id'这种格式会让flutter_form_builder自动将所有项的id和name组织到items数组中,正好匹配你需要的结构 - 表单验证:调用
saveAndValidate()可以自动验证所有输入框,确保数据合法 - 动态增删:示例中加入了添加/删除列表项的功能,你可以根据业务需求调整或移除这部分逻辑
内容的提问来源于stack exchange,提问作者Hardyson Arthy
相关产品推荐
相关产品推荐

