Flutter bool value resets after setstate in listview multiselect

1.1k views Asked by At

I have listview with checkboxtile filled with data in which when i will select option it will checkmark that item. Listview meant to be multi select option. There is model class for converting jsonresponse to data. UI code is working fine but ontap action causing bug in application. When on tap item selected it check the box and reset spontaneously. Issue is regarding selecting the checkbox on all item it reset automatically. It's look like something wrong with model class. Facing issue on emulator as well as physical device. Appreciate your time.

This is my CommonResponse class

class CommonResponse {
  final String id;
  final String name;
  bool isSelected = false;

  CommonResponse({this.id, this.name});

  factory CommonResponse.fromJson(Map<String, dynamic> json) {
    return CommonResponse(
      id: json['id'],
      name: json['name'] as String,
    );
  }
}

This is UI code:

import 'dart:convert';

import 'package:flutter/material.dart';

class WorkList extends StatefulWidget {
  Key key;

  WorkList({this.key}) : super(key: key);

  @override
  _WorkListState createState() => _WorkListState();
}

class _WorkListState extends State<WorkList> {
  Constants constants = Constants();
  List<String> selectedPrefIdList = List();

  Future<List<CommonResponse>> _getList() async {
    var jsonData =
        '[{"id": "1", "name": "1-2 day"}, {"id": "2", "name": "cameo"}, {"id": "5", "name": "movies"}, {"id": "6", "name": "ads"}]';

    List jsonResponse = json.decode(jsonData);
    var workPrefOutput =
        jsonResponse.map((list) => CommonResponse.fromJson(list)).toList();
    return workPrefOutput;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          child: FutureBuilder<List<CommonResponse>>(
            future: _getList(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return ListView.separated(
                    separatorBuilder: (context, index) {
                      return Divider();
                    },
                    itemCount: snapshot.data.length,
                    itemBuilder: (context, index) {
                      return CheckboxListTile(
                        title: Text(snapshot.data[index].name),
                        controlAffinity: ListTileControlAffinity.platform,
                        value: snapshot.data[index].isSelected,
                        onChanged: (value) {
                          setState(() {
                            snapshot.data[index].isSelected = value;
                            var selectedId = snapshot.data[index].id;
                            selectedPrefIdList.contains(selectedId)
                                ? selectedPrefIdList.remove(selectedId)
                                : selectedPrefIdList.add(selectedId);
                            // print(selectedPrefIdList);
                          });
                        },
                      );
                    });
              } else {
                return Center(
                  child: CircularProgressIndicator(),
                );
              }
            },
          ),
        ),
      ),
    );
  }
}
2

There are 2 answers

0
Talaal_M On

Im not sure if this will work, but maybe you can try switching this


snapshot.data[index].isSelected = value;

to this

snapshot.data[index].isSelected = !snapshot.data[index].isSelected;

2
vivek yadav On

I guess setstate is creating a problem. It is reloading future builder again. Because of this your selection is resetting