Home > Software design >  Adding to a list in flutter updates all the items in the list
Adding to a list in flutter updates all the items in the list

Time:12-26

I am trying to create a list of lists and every time I add to it it goes to the first list and updates it with new values. Any way to get it to not update the values in the first set?

List<bool> routineSelectedDays = [false, true, true, true, true, true, false];

List listOfSelectedDays = [];

   ElevatedButton(
     onPressed: (){
      listOfSelectedDays.add(routineSelectedDays);
     },  
     child: Text('Add Step')
   ),

Complete code:

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

  @override
  State<CustomRoutine2> createState() => _CustomRoutine2State();
}

class _CustomRoutine2State extends State<CustomRoutine2> {
  List<String> day = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
  List<bool> routineSelectedDays = [false, true, true, true, true, true, false];
  List listOfSelectedDays = [];

  List newList = [];

  int selectedIndex = 0;


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: EdgeInsets.all(18),
        child: SizedBox(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              SizedBox(
                height: 90,
                child: ListView.builder(
                    scrollDirection: Axis.horizontal,
                    itemCount: day.length,
                    itemBuilder: (context, index) {
                  return Padding(
                    padding: EdgeInsets.all(8.0),
                    child: DaySelectorButton(
                      onTap: () {
                        setState(() {
                          routineSelectedDays[index] =
                          !routineSelectedDays[index];
                         });
                      },
                      day: day[index],
                      toggle: routineSelectedDays[index],
                    ),
                  );
                }),
              ),
              ElevatedButton(onPressed: (){
                listOfSelectedDays.add(routineSelectedDays);
                print(listOfSelectedDays);
              }, child: Text('Add Step')),
              ElevatedButton(onPressed: (){
              }, child: Text('DEV'))
            ],
          ),
        ),
      ),
    );
  }
}

class DaySelectorButton extends StatelessWidget {
  const DaySelectorButton({
    Key? key,
    required this.toggle,
    required this.onTap,
    required this.day
  }) : super(key: key);

  final bool toggle;
  final VoidCallback onTap;
  final String day;

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: onTap,
      customBorder: const CircleBorder(),
      child: Ink(
        height: 40,
        width: 40,
        decoration: BoxDecoration(
          color: toggle ? kToggleEnabled : kToggleDisabled,
          shape: BoxShape.circle,
        ),
        child: Center(
          child: Text(
            day,
            textAlign: TextAlign.center,
            style: TextStyle(
              color: toggle ? Colors.black : Colors.grey,
            ),
          ),
        ),
      ),
    );
  }
}

And here is the output:

flutter: [true, true, true, true, true, true, true]
flutter: [[true, true, true, true, true, true, true]]
flutter: [false, false, true, true, true, true, true]
flutter: [[false, false, true, true, true, true, true], [false, false, true, true, true, true, true]]

CodePudding user response:

I figured out the reason for the above behavior after some research,

It's because,

  • same instance of routineSelectedDays is referred everytime listOfSelectedDays.add(routineSelectedDays) is called.
  • So changing routineSelectedDays will change all instances of routineSelectedDays in listOfSelectedDays.

To overcome this problem, we need to add copies instead of adding the actual object. i.e

Change

listOfSelectedDays.add(routineSelectedDays);

to

listOfSelectedDays.add([...routineSelectedDays]);

This will send the copy of the object instead of the actual object itself.

Output Now:

I/flutter ( 5565): [[false, false, true, true, true, true, false]]
I/flutter ( 5565): [[false, false, true, true, true, true, false], [false, false, false, true, true, true, false]]
  • Related