Idesh
Idesh

Reputation: 373

Image is not getting Updated even after using setState In Flutter

I'm Using ImagePicker and ImageCropper Package to pick and crop an image from the gallery or by capturing using a camera. Everything is working fine but the Picked image is not updating on UI even after using the SetState method. When I press the button for image Selection Again Previously selected Image Appears on the UI. I have no Idea what Is causing this delay.

My ImageProcessing Class Code

class ImageProcess{
  File _image, croppedFile;
  final picker = ImagePicker();
  //Getting Image From Gallery Or Camera.
  File getImage(BuildContext context) {
    showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.all(Radius.circular(15))),
            content: Container(
                height: 250,
                width: 250,
                child: Row(
                  children: [
                    IconButton(
                        iconSize: 100,
                        icon: Icon(Icons.insert_photo),
                        onPressed: () async {
                          final pickedFile = await picker.getImage(
                              source: ImageSource.gallery,imageQuality: 20);
                          _image = File(pickedFile.path);
                        croppedFile = await _cropImage();
                          Navigator.of(context).pop(true);
                        }),
                    IconButton(
                        iconSize: 100,
                        icon: Icon(Icons.camera),
                        onPressed: () async {
                          final pickedFile =
                          await picker.getImage(source: ImageSource.camera,imageQuality: 20);
                          _image = File(pickedFile.path);
                       croppedFile =  await _cropImage();
                          Navigator.of(context).pop(true);
                        })
                  ],
                )),
          );
        });
    return croppedFile;
  }

  //Cropping image which has been retrieved from gallery or gallery.
  Future<File> _cropImage() async {
   return await ImageCropper.cropImage(
        sourcePath: _image.path,
        aspectRatioPresets: Platform.isAndroid
            ? [
          CropAspectRatioPreset.square,
        ]
            : [
          CropAspectRatioPreset.square,
        ],
        androidUiSettings: AndroidUiSettings(
            toolbarTitle: 'Product Image Cropper',
            toolbarColor: kDarkYellow,
            toolbarWidgetColor: Colors.white,
            initAspectRatio: CropAspectRatioPreset.square,
            lockAspectRatio: false),
        iosUiSettings: IOSUiSettings(
          title: 'Product Image Cropper',
        ));
  }
}

Ui code

class AddItem extends StatefulWidget {
  @override
  _AddItemState createState() => _AddItemState();
}

class _AddItemState extends State<AddItem> {
  File croppedFile;
  ImageProcess im = new ImageProcess();
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
          backgroundColor: kVeryDarkBlue,
          body: SingleChildScrollView(
              child: Padding(
                padding: EdgeInsets.fromLTRB(20, 20, 20, 0),
                child: Column(
                  children: [
                    Container(
                        height: MediaQuery.of(context).size.height * 0.15,
                        width: MediaQuery.of(context).size.height * 0.15,
                        child: croppedFile == null
                            ? ClipOval(
                            child:
                            Image.asset('assets/images/image.png'))
                            : ClipOval(child: Image.file(croppedFile))),
                    RaisedButton(onPressed: () {
                        croppedFile= im.getImage(context);
                        setState(() {
                        });
                    },child: Text('Press'),)
                  ],
                ),
              ))),
    );
  }
}

I have tried every possible solution which came Into My mind.

Upvotes: 0

Views: 1800

Answers (2)

Claudio Castro
Claudio Castro

Reputation: 1569

Add Future in your getImage Method with some adjusts.

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: AddItem(),
    );
  }
}

class AddItem extends StatefulWidget {
  @override
  _AddItemState createState() => _AddItemState();
}

class _AddItemState extends State<AddItem> {
  File croppedFile;
  ImageProcess im = new ImageProcess();
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
          backgroundColor: Colors.blue,
          body: SingleChildScrollView(
              child: Padding(
            padding: EdgeInsets.fromLTRB(20, 20, 20, 0),
            child: Column(
              children: [
                Container(
                    height: MediaQuery.of(context).size.height * 0.15,
                    width: MediaQuery.of(context).size.height * 0.15,
                    child: croppedFile == null
                        ? ClipOval(
                            child: Image.asset('assets/images/image.png'))
                        : ClipOval(child: Image.file(croppedFile))),
                RaisedButton(
                  onPressed: () async {
                    // Add await here
                    croppedFile = await im.getImage(context);
                    setState(() {});
                  },
                  child: Text('Press'),
                )
              ],
            ),
          ))),
    );
  }
}

class ImageProcess {
  File _image, croppedFile;
  final picker = ImagePicker();
  //Getting Image From Gallery Or Camera.
  // now getImage is a future that wait for your choice.
  Future<File> getImage(BuildContext context) async {
    return await showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.all(Radius.circular(15))),
            content: Container(
                height: 250,
                width: 250,
                child: Row(
                  children: [
                    IconButton(
                        iconSize: 100,
                        icon: Icon(Icons.insert_photo),
                        onPressed: () async {
                          final pickedFile = await picker.getImage(
                              source: ImageSource.gallery, imageQuality: 20);
                          _image = File(pickedFile.path);
                          croppedFile = await _cropImage();
                          // croppedFile is the return of your ShowDialog
                          Navigator.of(context).pop(croppedFile);
                        }),
                    IconButton(
                        iconSize: 100,
                        icon: Icon(Icons.camera),
                        onPressed: () async {
                          final pickedFile = await picker.getImage(
                              source: ImageSource.camera, imageQuality: 20);
                          _image = File(pickedFile.path);
                          croppedFile = await _cropImage();
                          // croppedFile is the return of your ShowDialog
                          Navigator.of(context).pop(croppedFile);
                        })
                  ],
                )),
          );
        });
  }

  //Cropping image which has been retrieved from gallery or gallery.
  Future<File> _cropImage() async {
    return await ImageCropper.cropImage(
        sourcePath: _image.path,
        aspectRatioPresets: Platform.isAndroid
            ? [
                CropAspectRatioPreset.square,
              ]
            : [
                CropAspectRatioPreset.square,
              ],
        androidUiSettings: AndroidUiSettings(
            toolbarTitle: 'Product Image Cropper',
            toolbarColor: Colors.yellow,
            toolbarWidgetColor: Colors.white,
            initAspectRatio: CropAspectRatioPreset.square,
            lockAspectRatio: false),
        iosUiSettings: IOSUiSettings(
          title: 'Product Image Cropper',
        ));
  }
}

Upvotes: 2

Idesh
Idesh

Reputation: 373

After Tweaking Some Lines of I have figured Out Where Was the Problem.

Code For RaisedButton In UI

RaisedButton(
                  onPressed: () {
                    showDialog(
                        context: context,
                        builder: (context) {
                          return AlertDialog(
                            shape: RoundedRectangleBorder(
                                borderRadius:
                                    BorderRadius.all(Radius.circular(15))),
                            content: Container(
                                height: 250,
                                width: 250,
                                child: Row(
                                  children: [
                                    IconButton(
                                        iconSize: 100,
                                        icon: Icon(Icons.insert_photo),
                                        onPressed: () async {
                                          croppedFile =
                                              await im.getImageGallery();
                                          setState(() {});
                                          Navigator.pop(context);
                                        }),
                                    IconButton(
                                        iconSize: 100,
                                        icon: Icon(Icons.camera),
                                        onPressed: () async {
                                          croppedFile =
                                          await im.getImageCamera();
                                          setState(() {});
                                          Navigator.pop(context);
                                        })
                                  ],
                                )),
                          );
                        });
                  },
                  child: Text('Press'),
                )

Code For ImageProcessing Class. I have Divided Large Function Into Two Sub Functions.

  //Getting Image From Camera.
  Future<File> getImageCamera() async{
    final pickedFile = await picker.getImage(
        source: ImageSource.camera,imageQuality: 20);
    _image = File(pickedFile.path);
    return _cropImage();
  }
  //Getting Image From Gallery
  Future<File> getImageGallery() async{
    final pickedFile = await picker.getImage(
        source: ImageSource.gallery,imageQuality: 20);
    _image = File(pickedFile.path);
    return _cropImage();
  }

Upvotes: 0

Related Questions