Search code examples
flutterlistdartlistview

List.add not adding element to a boolean list in flutter


I have two Lists, imageFileList and values

// contains a list of image files which are captured from the camera page
    List<File> imageFileList = widget.imageFileList;
    // Values list is filled with boolean values which are defaulted to false and contains the same length as imageFileList
    List<bool> values = widget.values;

the imageFileList gets a new File added when user selects a picture from the gallery, and i want to simultaneously add another bool entry to the values List, as such -

    Future pickImage() async {
      try {
        final image =
            await ImagePicker().pickImage(source: ImageSource.gallery);
        if (image == null) return;
        final imageTemp = File(image.path);

        setState(() {
// adding a new image to imageFileList
          imageFileList.add(imageTemp);
// adding a new bool to values List
          values.add(false);
        });

        // rebuildAllChildren(context);
      } catch (e) {
        print(e);
      }
    }

When i use pickImage(), the file gets added to the imageFileList, but the false bool is not getting added to the values List.

debug output shows this line when i print the lengths of imageFileList and values List -

              print("imagelist = " +
                      imageFileList.length.toString());
                  print("values = " +
                      values.length.toString());

// debug output
I/flutter (20710): imagelist = 5
I/flutter (20710): values = 4

any suggestions on what might be wrong?

here is the full code -

  Widget build(BuildContext context) {
    // contains a list of image files which are captured from the camera page
    List<File> imageFileList = widget.imageFileList;
    // Values list is filled with boolean values which are defaulted to false and contains the same length as imageFileList
    List<bool> values = widget.values;

    Future pickImage() async {
      try {
        final image =
            await ImagePicker().pickImage(source: ImageSource.gallery);
        if (image == null) return;
        final imageTemp = File(image.path);

        setState(() {
          imageFileList.add(imageTemp);
          values.add(false);
        });

        // rebuildAllChildren(context);
      } catch (e) {
        print(e);
      }
    }

    getStoragePermissionStatus() async {
      await Permission.camera.request();
      var status = await Permission.storage.status;
      if (status.isGranted) {
        log('Camera Permission: GRANTED');
        setState(() {
          _isStoragePermissionGranted = true;
        });

        // asking the user to select an image IF they grant storage permission
        await pickImage();
        print(_isStoragePermissionGranted);
      } else {
        log('Camera Permission: DENIED');
      }
    }

    return WillPopScope(
      onWillPop: (() => onWillPop(context)),
      child: Scaffold(
        backgroundColor: Color(lightBlueColor),
        body: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Padding(
                padding: EdgeInsets.all(8.0),
                child: Text(
                  'Captures',
                  style: TextStyle(
                    fontSize: 32.0,
                    color: Colors.white,
                  ),
                ),
              ),
              Container(
                height: returnDeviceHeight(context) / 1.2,
                width: returnDeviceWidth(context),
                child: ListView.builder(
                  itemCount: imageFileList.length,
                  itemBuilder: (BuildContext context, int index) {
                    String key = imageFileList[index].toString();
                    return Column(
                      children: <Widget>[
                        Container(
                          width: returnDeviceWidth(context) - 10,
                          height: returnDeviceHeight(context) / 2,
                          decoration: BoxDecoration(
                            borderRadius:
                                BorderRadius.all(Radius.circular(8.0)),
                            color: Colors.black,
                            border: Border.all(
                              color: values[index] ? Colors.green : Colors.red,
                              width: 4,
                            ),
                          ),
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Expanded(
                                child: Center(
                                  child: InkWell(
                                    onTap: () {
                                      Navigator.of(context).pushReplacement(
                                        MaterialPageRoute(
                                          builder: (context) => PreviewScreen(
                                            fileList: imageFileList,
                                            imageFile: imageFileList[index],
                                          ),
                                        ),
                                      );
                                    },
                                    child: Image.file(
                                      imageFileList[index],
                                      fit: BoxFit.cover,
                                    ),
                                  ),
                                ),
                              ),
                          
                            ],
                          ),
                        ),
                        Divider(
                          height: 2.0,
                        ),
                      ],
                    );
                  },
                ),
              ),
              ReturnSizedBox10(),
              InkWell(
                onTap: () async {
                  await getStoragePermissionStatus();
                },
                child: Container(
                  width: returnDeviceWidth(context) - 10,
                  height: 50,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(Radius.circular(8.0)),
                    color: Color(darkBlueColor),
                  ),
                  child: Center(
                    child: LightBluefontstyleMont(
                        text: "Pick an image from gallery", size: 20),
                  ),
                ),
              ),
              InkWell(
                onTap: () async {
                  print("imagelist = " +
                      imageFileList.length.toString());
                  print("values = " +
                      values.length.toString());
                },
                child: Container(
                  width: returnDeviceWidth(context) - 10,
                  height: 50,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(Radius.circular(8.0)),
                    color: Colors.white,
                  ),
                  child: Center(
                    child: LightBluefontstyleMont(text: "Done", size: 20),
                  ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }

I have tried to with the setState and without it, however both times, only the imageFileList gets the new entry added.

I need to add a new entry to values List when the imageFileList gets a new entry added to it.


Solution

  • Well, turns out every time I add a new image to the imageFileList, the values List gets reset; to the value it had in widget.values.

    Fixed it by using initState -

      late List<File> imageFileList;
      late List<dynamic> values;
    
      @override
      void initState() {
        // contains a list of image files which are captured from the camera page
        imageFileList = widget.imageFileList;
        // Values list is filled with boolean values which are defaulted to false and contains the same length as imageFileList
        values = widget.values.toList();
        // TODO: implement initState
        super.initState();
      }