小能豆

动态添加和删除 TextFormFields

flutter

我正在尝试创建一个“创建任务”页面,用户可以在其中添加或删除任务的待办事项文本字段。我创建了一个 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),
        ),
      ),
    );
  }
}

在尝试删除“学习”之前

尝试删除“学习”后

我期望与其控制器对应的文本表单字段将被删除..但实际发生的是最后一个文本表单字段被删除。


阅读 199

收藏
2024-02-23

共2个答案

小能豆

TextFormField缺少控制器属性。

请为其分配一个控制器。

...
return TextFormField(
  controller: controller,
  decoration: ...,
);
...
2024-02-23
小能豆

  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..
2024-02-23