I have tried to make an image picker widget, I named it ImagePickerWidget, it looks like this
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(widget.label),
VerticalSeparator(height: 1),
InkWell(
onTap: () async {
XFile? imageFile = await ImagePicker().pickImage(source: ImageSource.camera);
if(imageFile != null){
setState(() {
image = File(imageFile.path);
});
}
},
child: SizedBox(
width: SizeConfig.safeBlockHorizontal*20,
height: SizeConfig.safeBlockHorizontal*20,
child: image!=null?
Image.file(image!, fit: BoxFit.cover,):
Image.asset('assets/illustration/ill_add_photo.png', package: 'design_module', fit: BoxFit.cover,),
)
)
],
)
I will call this widget every time I need image picker on my forms(CustomFormWidget), but I have trouble to send the image value in ImagePickerWidget to CustomFormWidget. I am thinking making it like onChanged method on TextFormField where I can get the value through function parameter. Any idea?
Your question isn’t too clear, but I think you want to make a reusable widget and pass the picked file as the result.
Simply accept a callback/function:
class MyImagePickerWidget extends StatefulWidget {
final Function(File?) onChanged; // --> add this
MyImagePickerWidget({
Key? key,
required this.onChanged,
}) : super(key: key);
}
and then, in the onTap
of the InkWell
, call the function:
onTap: () async {
XFile? imageFile = await ImagePicker().pickImage(source: ImageSource.camera);
if(imageFile != null){
setState(() {
image = File(imageFile.path);
});
widget.onChanged(image); // --> Call onChanged here.
}
},
and its’ usage would be;
MyImagePickerWidget(
onChanged: (File? file) {
setState(() {
_selectedImage = file;
});
},
),
Complete example:
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: CustomFormWidget(),
),
);
}
}
class CustomFormWidget extends StatefulWidget {
@override
_CustomFormWidgetState createState() => _CustomFormWidgetState();
}
class _CustomFormWidgetState extends State<CustomFormWidget> {
File? _selectedImage;
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyImagePickerWidget(
onChanged: (File? file) {
setState(() {
_selectedImage = file;
});
},
),
SizedBox(height: 20),
Text(_selectedImage != null
? 'Image selected: ${_selectedImage!.path}'
: 'No image selected'),
],
),
);
}
}
class MyImagePickerWidget extends StatefulWidget {
final Function(File?) onChanged;
const MyImagePickerWidget({
Key? key,
required this.onChanged,
}) : super(key: key);
@override
_MyImagePickerWidgetState createState() => _MyImagePickerWidgetState();
}
class _MyImagePickerWidgetState extends State<MyImagePickerWidget> {
File? image;
@override
void initState() {
super.initState();
image = widget.initialValue;
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(widget.label),
SizedBox(height: 8),
InkWell(
onTap: () async {
XFile? imageFile = await ImagePicker().pickImage(source: ImageSource.gallery);
if(imageFile != null){
setState(() {
image = File(imageFile.path);
});
widget.onChanged(image);
}
},
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
),
child: image != null
? Image.file(image!, fit: BoxFit.cover)
: Icon(Icons.add_a_photo, size: 50),
)
)
],
);
}
}