Reputation: 373
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
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
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