我正在尝试创建一个“创建任务”页面,用户可以在其中添加或删除任务的待办事项文本字段。我创建了一个 TextEditingController 列表来动态添加和删除,以便将它们映射到文本表单字段。我添加时没有问题,但是当我尝试从列表中删除特定的 TextEditingController (通过索引或引用)时,它总是会导致删除最后一个文本表单字段..
import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:gdsc_session2/constants/image_strings.dart'; import '../widgets/text_field.dart'; class NewTask extends StatefulWidget { const NewTask({super.key}); @override State<NewTask> createState() => _NewTaskState(); } class _NewTaskState extends State<NewTask> { final GlobalKey<FormState> formKey = GlobalKey(); final List<TextEditingController> controllers = []; @override Widget build(BuildContext context) { return Scaffold( body: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Form( key: formKey, child: ListView( children: [ for (var ctrl in controllers) ...[ GTextField( hintText: 'Todo ${controllers.indexOf(ctrl) + 1}', prefixIcon: Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: SvgPicture.asset( GImageStrings.clipboard, width: 25, ), ), suffixIcon: IconButton( // Delete Button onPressed: () { setState(() {}); removeTextField(controllers.indexOf(ctrl)); }, icon: const Icon(Icons.clear)), controller: ctrl, ), const SizedBox( height: 15, ), ], // Add Button Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( width: 200, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Colors.blue.withOpacity(0.2), ), onPressed: () { setState(() { addTextField(); }); }, child: const Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.add_circle), SizedBox( width: 10, ), Text( 'Add', style: TextStyle(color: Colors.white), ) ], )), ), ], ) ], ), ), ) ], ), ); } void addTextField() { controllers.add(TextEditingController()); } void removeTextField(int index) { controllers.removeAt(index); } }
这是我的自定义文本表单字段
import 'package:flutter/material.dart'; class GTextField extends StatelessWidget { final Widget? prefixIcon; final Widget? suffixIcon; final String hintText; final TextEditingController controller; const GTextField({ super.key, this.prefixIcon, this.suffixIcon, required this.hintText, required this.controller, }); @override Widget build(BuildContext context) { return TextFormField( decoration: InputDecoration( hintText: hintText, contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 15), prefixIcon: prefixIcon, prefixIconConstraints: const BoxConstraints(), suffixIcon: suffixIcon, filled: true, fillColor: Colors.white10.withOpacity(0.05), border: OutlineInputBorder( borderSide: BorderSide.none, borderRadius: BorderRadius.circular(30), ), errorBorder: OutlineInputBorder( borderSide: const BorderSide(color: Colors.red), borderRadius: BorderRadius.circular(30), ), ), ); } }
在尝试删除“学习”之前
尝试删除“学习”后
我期望与其控制器对应的文本表单字段将被删除..但实际发生的是最后一个文本表单字段被删除。
TextFormField缺少控制器属性。
TextFormField
请为其分配一个控制器。
... return TextFormField( controller: controller, decoration: ..., ); ...
List<TextEditingController> _controllers = [TextEditingController()]; Scaffold( body: ListView.builder( itemCount: _controllers.length, itemBuilder: (context, index) { return Padding( padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), child: Row( children: [ Expanded( child: TextFormField( controller: _controllers[index], decoration: InputDecoration( hintText: 'Enter text', border: OutlineInputBorder(), ), ), ), IconButton( icon: Icon(Icons.remove), onPressed: () { setState(() { _controllers.removeAt(index).dispose(); }); }, ), ], ), ); }, ), floatingActionButton: FloatingActionButton( onPressed: () { setState(() { _controllers.add(TextEditingController()); }); }, child: Icon(Icons.add), ), ) @override void dispose() { for (var controller in _controllers) { controller.dispose(); } super.dispose(); } Enjoy..