Home > database >  Flutter - Having trouble refactoring an AlertDialog widget
Flutter - Having trouble refactoring an AlertDialog widget

Time:01-27

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!


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);
    }
  }

CodePudding user response:

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,
                ),
              ),
            ),
          ],
        );
      });
  •  Tags:  
  • Related