Flutter Form Builder动态表单字段删除后UI与实际状态不一致问题
Flutter Form Builder动态表单UI不同步问题
我在测试Flutter Form Builder的动态表单功能,表单支持自由添加、删除字段。原代码存在问题:点击字段对应的删除按钮时,总是删除最新添加的FormBuilderTextField,而非目标字段。
我尝试修复后,表单底层状态已符合预期(点击提交后打印的_formKey状态正确),但UI未同步更新,仍显示最新字段被删除的错误状态:
- 初始状态:表单包含一个起始字段和3个动态添加的字段(字段#1、#2、#3)
- 点击字段#3的删除按钮后:UI错误删除了最新字段,同时底层状态也异常
- 点击提交按钮后:底层状态恢复正确,但UI依旧显示错误状态
修改后的dynamic_fields.dart代码如下:
import 'package:flutter/material.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:form_builder_validators/form_builder_validators.dart'; class DynamicFields extends StatefulWidget { const DynamicFields({Key? key}) : super(key: key); @override State<DynamicFields> createState() => _DynamicFieldsState(); } class _DynamicFieldsState extends State<DynamicFields> { final _formKey = GlobalKey<FormBuilderState>(); final Map<int, Widget> fields = {}; int idCounter = 1; String savedValue = ''; @override void initState() { savedValue = _formKey.currentState?.value.toString() ?? ''; super.initState(); } @override Widget build(BuildContext context) { return FormBuilder( key: _formKey, // IMPORTANT to remove all references from dynamic field when delete clearValueOnUnregister: true, child: Column( children: <Widget>[ const SizedBox(height: 20), FormBuilderTextField( name: 'name', validator: FormBuilderValidators.required(), decoration: const InputDecoration( label: Text('Started field'), ), ), ...fields.values, const SizedBox(height: 10), Row( children: <Widget>[ Expanded( child: MaterialButton( color: Theme.of(context).colorScheme.secondary, child: const Text( "Submit", style: TextStyle(color: Colors.white), ), onPressed: () { _formKey.currentState!.saveAndValidate(); setState(() { savedValue = "Submit button pressed - current form state: ${_formKey.currentState!.value.toString()}"; _formKey.currentState?.value.toString() ?? ''; }); }, ), ), const SizedBox(width: 20), Expanded( child: MaterialButton( color: Theme.of(context).colorScheme.secondary, child: const Text( "Add field", style: TextStyle(color: Colors.white), ), onPressed: () { setState(() { fields[idCounter] = NewTextField( name: 'name_${idCounter}', id: idCounter, onDelete: (int id) { setState(() { fields.remove(id); _formKey.currentState!.save(); print("Removed field #$id - current form state: ${_formKey.currentState!.value.toString()}"); savedValue = "Removed field #$id - current form state: ${_formKey.currentState!.value.toString()}"; }); }, ); idCounter++; }); }, ), ), ], ), const Divider(height: 40), Text(savedValue), ], ), ); } } class NewTextField extends StatelessWidget { const NewTextField({ super.key, required this.name, required this.id, required this.onDelete, }); final String name; final int id; final void Function(int) onDelete; @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.only(bottom: 8), child: Row( children: [ Expanded( child: FormBuilderTextField( name: name, decoration: InputDecoration( label: Text('Field #$id'), ), ), ), IconButton( icon: const Icon(Icons.delete_forever), onPressed: () => onDelete(id), ), ], ), ); } }
内容的提问来源于stack exchange,提问作者mtao
相关产品推荐
相关产品推荐

