skip to Main Content

I am working with dynamic list which add and delete items in the list. but when i delete a specific index with removeAt() method it always delete the last item, below is all code

import 'package:bizzsmart_web/constants/constants.dart';
import 'package:bizzsmart_web/model/expense_item_model.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class TestPage extends StatefulWidget {
  const TestPage({Key? key}) : super(key: key);

  @override
  State<TestPage> createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  List<ExpenseItemModel> expenses =
      List.generate(1, (index) => ExpenseItemModel());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          sbh(150),
          Expanded(
            child: ListView.builder(
              itemCount: expenses.length,
              itemBuilder: (c, i) {
                return Column(
                  children: [
                    Row(
                      children: [
                        IconButton(
                          onPressed: () {
                            if (i == expenses.length - 1 ||
                                (expenses.length == 1)) return;
                            expenses.removeAt(i);
                            setState(() {});
                          },
                          icon: const Icon(CupertinoIcons.delete),
                        ),
                        Expanded(
                          child: TextField(
                            onChanged: (val) {
                              if (expenses.length - 1 == i) {
                                expenses.add(ExpenseItemModel());
                              }
                              setState(() {});
                            },
                            decoration: InputDecoration(
                              border: border,
                              enabledBorder: border,
                              focusedBorder: border,
                            ),
                          ),
                        ),
                        sbw(50),
                      ],
                    ),
                    sbh(10),
                  ],
                );
              },
            ),
          ),
        ],
      ),
    );
  }

  final border = OutlineInputBorder(
    borderRadius: BorderRadius.circular(8),
  );
}

and Dart pad link : https://dartpad.dev/?id=9f87f484c1dc201b4d0c10d504eb7d1b

Somebody please help.

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry’s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.

2

Answers


  1. The problem is that you don’t keep track on which TextField corresponds with which expense. To solve it you need to define controllers that you can give the TextFields. Like this for example:

    class _TestPageState extends State<TestPage> {
      List<ExpenseItemModel> expenses = [ExpenseItemModel()];
      List<TextEditingController> controllers = [TextEditingController()];
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            children: [
              SizedBox(height: 150),
              Expanded(
                child: ListView.builder(
                  itemCount: expenses.length,
                  itemBuilder: (c, i) {
                    return Column(
                      children: [
                        Row(
                          children: [
                            IconButton(
                              onPressed: () {
                                if (i == expenses.length - 1 ||
                                    (expenses.length == 1)) return;
                                expenses.removeAt(i);
                                controllers.removeAt(i);
                                setState(() {});
                              },
                              icon: Icon(CupertinoIcons.delete),
                            ),
                            Expanded(
                              child: TextField(
                                controller: controllers[i],
                                onChanged: (val) {
                                  if (expenses.length - 1 == i) {
                                    expenses.add(ExpenseItemModel());
                                    controllers.add(TextEditingController());
                                  }
                                  setState(() {});
                                },
                                decoration: InputDecoration(
                                  border: border,
                                  enabledBorder: border,
                                  focusedBorder: border,
                                ),
                              ),
                            ),
                            SizedBox(width: 50),
                          ],
                        ),
                        SizedBox(height: 10),
                      ],
                    );
                  },
                ),
              ),
            ],
          ),
        );
      }
    
      final border = OutlineInputBorder(
        borderRadius: BorderRadius.circular(8),
      );
    }
    

    Note I also changed the way you initialize expenses it a more concise way.

    Instead of having two lists like this you might even want to consider making the TextEditingController part of your ExpenseItemModel and then do something like controller: expenses[i].controller,

    Login or Signup to reply.
  2. You have to write code as below. You must have to attach controller to Textfield.

    class _TestPageState extends State<TestPage> {
      List<ExpenseItemModel> expenses = List.generate(1, (index) => ExpenseItemModel());
      List<TextEditingController> controllers
      = List.generate(1, (index) => TextEditingController());
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            children: [
              SizedBox(height: 150),
              Expanded(
                child: ListView.builder(
                  itemCount: expenses.length,
                  itemBuilder: (c, i) {
                    return Column(
                      children: [
                        Row(
                          children: [
                            IconButton(
                              onPressed: () {
                                if (expenses.length == 1) return;
                                expenses.removeAt(i);
                                controllers.removeAt(i);
                                setState(() {});
                              },
                              icon: Icon(CupertinoIcons.delete),
                            ),
                            Expanded(
                              child: TextField(
                                controller: controllers[i],
                                onChanged: (val) {
                                  if (expenses.length - 1 == i) {
                                    expenses.add(ExpenseItemModel());
                                    controllers.add(TextEditingController());
                                  }
                                  controllers[i].text = val.toString();
                                  setState(() {});
                                },
                                decoration: InputDecoration(
                                  border: border,
                                  enabledBorder: border,
                                  focusedBorder: border,
                                ),
                              ),
                            ),
                            SizedBox(width: 50),
                          ],
                        ),
                        SizedBox(height: 10),
                      ],
                    );
                  },
                ),
              ),
            ],
          ),
        );
      }
    
      final border = OutlineInputBorder(
        borderRadius: BorderRadius.circular(8),
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search