简体   繁体   中英

ListView ListTile Switches toggle simultaneously in Flutter

I have a ListView of ListTile 's with trailing Switch 'es. My problem is when I toggle any switch, other switches toggle too, although they shouldn't.

Here's the look:

在此处输入图像描述

Here's the code (with clutter removed):

//Schedule program class
class ScheduleProgram {
  bool enabled;
  bool isStart;
  TimeOfDay time;
  int duration;
  List<bool> dow;
  ScheduleProgram(
      {this.enabled, this.isStart, this.time, this.duration, this.dow});
}

//Init list of programs
List<ScheduleProgram> scheduleList = 
  List<ScheduleProgram>.filled(10,
      ScheduleProgram(
          enabled: false,isStart: false,time: TimeOfDay(minute: 0, hour: 0),
          duration: 0,dow: [false, false, false, false, false, false, false]),
      growable: false );

...
//And now build the list
  int _selectedProgramIndex = 0;
  ListView _generateTaskButtonList(BuildContext context) {
    return ListView.separated(
      separatorBuilder: (BuildContext context, int index) {
        return SizedBox(height: 10);
      },        
      itemCount: 10,          
      itemBuilder: (BuildContext context, int index) {
        return ClipRRect(
          child: ListTile(
            selected: index == _selectedProgramIndex,
            leading: IconButton(
              icon: const Icon(Icons.edit, size: 30),
              onPressed: () {
                setState(() {
                  log("Edit $index pressed");
                });
              },
            ),
            title: Text('P' + index.toString() + ':'),
            subtitle: Text('-'),
            trailing: Padding(
              child: Transform.scale(
                child: Switch(
                  onChanged: (v) {
                    setState(() {
                      scheduleList[index].enabled = v;
                      log("P$index is $v, scheduleList enabled = " +
                          scheduleList[index].enabled.toString());
                    });
                  },
                  value: scheduleList[index].enabled,
                ),
              ),
            ),
            onTap: () {
              log('Tapped #' + index.toString());
              setState(() {
                _selectedProgramIndex = index;
              });
            },
          ),
        );
      },
    );
  }
}

This happens because List.filled() creates a list where all the elements are actually using the same object. In other words, your scheduleList has the same object over and over again, not different objects. To create a new object for each index, use List.generate() instead.

Just replace your //Init list of programs code with this and you're good to go:

//Init list of programs
  List<ScheduleProgram> scheduleList = List<ScheduleProgram>.generate(
      10,
      (index) => ScheduleProgram(
          enabled: false,
          isStart: false,
          time: TimeOfDay(minute: 0, hour: 0),
          duration: 0,
          dow: [false, false, false, false, false, false, false]),
      growable: false);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM