我有一个动态表单列表,需要在两个域之间动态添加和删除表单域。我可以从列表底部正确添加/删除表单域。
但是,当我尝试在两个表单域之间添加一个表单域时,该域的数据没有正确更新。
如何正确地在两个字段之间添加字段并正确地填充数据?
import 'package:flutter/material.dart';
class DynamicFormWidget extends StatefulWidget {
const DynamicFormWidget({Key? key}) : super(key: key);
@override
State<DynamicFormWidget> createState() => _DynamicFormWidgetState();
}
class _DynamicFormWidgetState extends State<DynamicFormWidget> {
List<String?> names = [null];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Dynamic Forms'),
),
body: ListView.separated(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 16),
itemBuilder: (builderContext, index) => Row(
children: [
Flexible(
child: TextFormField(
initialValue: names[index],
onChanged: (name) {
names[index] = name;
debugPrint(names.toString());
},
decoration: InputDecoration(
hintText: 'Enter your name',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8))),
),
),
Padding(
padding: const EdgeInsets.all(8),
child: IconButton(
onPressed: () {
setState(() {
if(index + 1 == names.length){
names.add( null); debugPrint('Added: $names');
} else {
names.insert(index + 1, null); debugPrint('Added [${index+1}]: $names');
}
});
},
color: Colors.green,
iconSize: 32,
icon: const Icon(Icons.add_circle)),
),
Padding(
padding: const EdgeInsets.all(8),
child: IconButton(
onPressed: (index == 0&& names.length == 1)
? null
: () {
setState(() {
names.removeAt(index);
});
debugPrint('Removed [$index]: $names');
},
color: Colors.red,
iconSize: 32,
icon: const Icon(Icons.remove_circle)),
),
],
),
separatorBuilder: (separatorContext, index) => const SizedBox(
height: 16,
),
itemCount: names.length,
),
);
}
}
2条答案
按热度按时间3htmauhk1#
基本上,问题是Flutter搞不清
TextFormField
列表中的谁是谁。要解决此问题,只需将key添加到您的
TextFormField
,以便它可以由Flutter唯一标识:如果你想了解更多关于键的知识和正确使用方法,可以看看this。
js81xvg62#
小部件
AnimatedList
解决了这个问题,它像列表一样跟踪小部件,并使用了一个构建函数,所以很容易与另一个列表同步元素。如果你最终拥有了大量的表单,你可以使用InheritedWidget
来简化代码。在这个示例中,我使用
TextEditingController
从表单代码部分进行抽象,并使用值进行初始化(小部件继承自ChangeNotifier
,因此更改值将更新表单小部件中的文本),为了简单起见,它只在索引处添加(使用通用文本)和删除。要使每个
CustomLineForm
对其他CustomLineForm
起React(例如:如果只剩下一个条目,则禁用删除)使用StreamBuilder
或ListModel
来通知更改,并使每个条目评估是否需要更新而不是重建所有内容。