Search code examples
flutterdartimage-galleryflutter-futurebuilderimagepicker

Flutter display image picked from gallery


I am simply trying to pick an image and display it inside my app. For that I am using Flutter Image Picker. I added all the dependencies and I can select an image but I can not display it...

This is what I tried:

class _AddMemoryPageState extends State<AddMemoryPage> {
  final picker = ImagePicker();
  late Future<PickedFile?> pickedFile;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: AppColors.secondary,
      body: SafeArea(
        child: Column(
          children: [
            Row(
              children: [
                Padding(
                  padding: EdgeInsets.only(
                    top: 15,
                    left: 25,
                  ),
                  child: IconButtonWithExpandedTouchTarget(
                    onTapped: () {
                      Navigator.pop(context);
                    },
                    svgPath: 'assets/icons/down.svg',
                  ),
                ),
              ],
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                IconButtonWithExpandedTouchTarget(
                  onTapped: () async {
                    pickedFile = picker
                        .getImage(
                          source: ImageSource.camera,
                        )
                        .whenComplete(() => {setState(() {})});
                  },
                  svgPath: 'assets/icons/camera.svg',
                ),
                SizedBox(
                  width: scaleWidth(50),
                ),
                IconButtonWithExpandedTouchTarget(
                  onTapped: () async {
                    pickedFile = picker
                        .getImage(
                          source: ImageSource.gallery,
                        )
                        .whenComplete(() => {setState(() {})});
                  },
                  svgPath: 'assets/icons/gallery.svg',
                ),
              ],
            ),
            FutureBuilder(
              future: pickedFile,
              builder: (context, data) {
                if (data.hasData) {
                  return Container(
                    height: 200.0,
                    child: Image.file(
                      data.data as File,
                      fit: BoxFit.contain,
                      height: 200.0,
                    ),
                    color: Colors.blue,
                  );
                }
                return Container(
                  height: 200.0,
                  color: Colors.blue,
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

However this is not working:

LateInitializationError: Field 'pickedFile' has not been initialized.

What am I missing here? What is the proper way to handle this? I couldn't find any up-to-date tutorial/docs on this.. Let me know if you need any more info!


Solution

  • You basically forgot to transform de PickerFile in a File and init the variable pickedFile late Future<PickedFile?> pickedFile = Future.value(null);.

    To transform the PickerFile in a file, you just need to do:

    File(data.data!.path)
    

    I made some modifies at your code, that can show the image now:

      final picker = ImagePicker();
      late Future<PickedFile?> pickedFile = Future.value(null);
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.blueGrey,
          body: SafeArea(
            child: Column(
              children: [
                Row(
                  children: [
                    Padding(
                      padding: EdgeInsets.only(
                        top: 15,
                        left: 25,
                      ),
                      child: IconButton(
                        onPressed: () {
                          Navigator.pop(context);
                        },
                        icon: Icon(Icons.download_rounded),
                      ),
                    ),
                  ],
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    IconButton(
                      onPressed: () async {
                        pickedFile = picker.getImage(source: ImageSource.camera).whenComplete(() => {setState(() {})});
                      },
                      icon:Icon(Icons.add)
                    ),
                    SizedBox(
                      width: 100,
                    ),
                    IconButton(
                      onPressed: () async {
                        pickedFile = picker
                            .getImage(
                          source: ImageSource.gallery,
                        )
                            .whenComplete(() => {setState(() {})});
                      },
                      icon:Icon(Icons.photo_camera_back),
                    ),
                  ],
                ),
                FutureBuilder<PickedFile?>(
                  future: pickedFile,
                  builder: (context, snap) {
                    if (snap.hasData) {
                      return Container(
                        child: Image.file(
                          File(snap.data!.path),
                          fit: BoxFit.contain,
                        ),
                        color: Colors.blue,
                      );
                    }
                    return Container(
                      height: 200.0,
                      color: Colors.blue,
                    );
                  },
                ),
              ],
            ),
          ),
        );
      }