Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Flutter – Having trouble refactoring an AlertDialog widget

I have built an AlertDialog widget to allow users to upload photos from the gallery or the camera.

This widget will be used in multiple places throughout the app so I wanted to refactor it into a reusable widget, but I am stuck on how to proceed. The issue I’m facing is that I need to do different things with the resulting image, so I’m looking for a way to have the AlertDialog widget return the image back to the calling parent widget.

Ideas would be much appreciated!

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel


Example of triggering the AlertDialog widget on tap:

onTap: () {
  showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('Attach Photo'),
          actions: [
            RadioListTile(
              title: Text('Camera'),
              value: 1,
              groupValue: 3,
              onChanged: (int? value) {
                Navigator.pop(context);
                Helper.of(context)
                    .getImage(fromCamera: true)
                    .then((image) {
                  // Do things with image here
                });
              },
            ),
            RadioListTile(
              title: Text('Gallery'),
              value: 2,
              groupValue: 3,
              onChanged: (int? value) {
                Navigator.pop(context);
                Helper.of(context)
                    .getImage(fromCamera: false)
                    .then((image) {
                  // Do things with image here
                });
              },
            ),
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: const Text(
                'Cancel',
                style: TextStyle(
                  fontSize: 15,
                ),
              ),
            ),
          ],
        );
      });
}

Code for the getImage helper function:

  // ImagePicker to get photo from gallery or camera
  Future<File?> getImage({required bool fromCamera}) async {
    final ImagePicker _picker = ImagePicker();
    final ImageSource _source =
        fromCamera ? ImageSource.camera : ImageSource.gallery;
    final XFile? image = await _picker.pickImage(source: _source);
    if (image != null) {
      return File(image.path);
    }
  }

>Solution :

I would just add another global Function

Future showImageDialog(Function(Image?) onImagePicked)
 => showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('Attach Photo'),
          actions: [
            RadioListTile(
              title: Text('Camera'),
              value: 1,
              groupValue: 3,
              onChanged: (int? value) {
                Navigator.pop(context);
                Helper.of(context)
                    .getImage(fromCamera: true)
                    .then((image) {
                  onImagePicked(image);
                });
              },
            ),
            RadioListTile(
              title: Text('Gallery'),
              value: 2,
              groupValue: 3,
              onChanged: (int? value) {
                Navigator.pop(context);
                Helper.of(context)
                    .getImage(fromCamera: false)
                    .then((image) {
                 onImagePicked(image);
                });
              },
            ),
            TextButton(
              onPressed: () { 
 onImagePicked(null);
Navigator.pop(context),
}
              child: const Text(
                'Cancel',
                style: TextStyle(
                  fontSize: 15,
                ),
              ),
            ),
          ],
        );
      });

or just use Navigator.pop

Future<Image?> showImageDialog()
 => showDialog<Image?>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('Attach Photo'),
          actions: [
            RadioListTile(
              title: Text('Camera'),
              value: 1,
              groupValue: 3,
              onChanged: (int? value) {
                Navigator.pop(context);
                Helper.of(context)
                    .getImage(fromCamera: true)
                    .then((image) {
                  Navigator.of(context).pop(image);
                });
              },
            ),
            RadioListTile(
              title: Text('Gallery'),
              value: 2,
              groupValue: 3,
              onChanged: (int? value) {
                Navigator.pop(context);
                Helper.of(context)
                    .getImage(fromCamera: false)
                    .then((image) {
                 Navigator.of(context).pop(image);
                });
              },
            ),
            TextButton(
              onPressed: () { 
 Navigator.of(context).pop(null);
},
              child: const Text(
                'Cancel',
                style: TextStyle(
                  fontSize: 15,
                ),
              ),
            ),
          ],
        );
      });
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading