I have a profile picture card which I am using in 3 different places. I am passing some parameters to the ProfilePictureCard
to show camera button.
For an example if the ProfilePictureCard
is used in a ProfilePage the camera button will be hidden and if the said card is shown in a EditProfilePage the camera button will be visible.
This is the code for ProfilePictureCard
:
class ProfilePictureCard extends StatefulWidget {
final bool? isSetProfilePage;
final bool? isEditable;
File? imageFile;
final String? imageUrl;
ProfilePictureCard({
Key? key,
this.isSetProfilePage = false,
this.isEditable = false,
this.imageFile,
this.imageUrl,
}) : super(key: key);
@override
_ProfilePictureCardState createState() => _ProfilePictureCardState();
}
class _ProfilePictureCardState extends State<ProfilePictureCard> {
@override
void initState() {
super.initState();
print('Image Url: ${widget.imageUrl}');
}
@override
Widget build(BuildContext context) {
return Container(
height: 150,
width: 150,
child: Stack(
children: [
Stack(
children: [
Center(
child: _buildProfilePicture(),
),
widget.isEditable == true
? Positioned(
bottom: 0,
left: 55,
right: 55,
child: CameraButton(
onPressed: () {
_handleChangeProfilePicture();
},
),
)
: Container(),
],
),
],
),
);
}
Widget _buildProfilePicture() {
return Container(
height: 100,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: CustomColors.semiSecondary,
width: 1,
),
),
child: _buildImage(),
);
}
Widget _buildImage() {
return ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: widget.imageFile != null
? Image.file(
widget.imageFile!,
fit: BoxFit.cover,
)
: Image.network(
widget.imageUrl ?? 'https://picsum.photos/200',
fit: BoxFit.cover,
),
);
}
void _handleChangeProfilePicture() async {
final result = await showDialog(
context: context,
builder: (context) {
return CameraDialog();
},
);
print("Result: $result");
if (result != null) {
setState(() {
widget.imageFile = result;
});
print(widget.imageFile);
}
}
}
_handleChangeProfilePicture takes a picture from either gallery or camera and returns it using Navigator.of(context).pop(finalImage);
In my EditProfilePage I have a Update
Button which for now only prints out the selected images path.
The EditProfilePage
file looks like this:
class _EditProfilePage extends State<EditProfilePage {
File? imageFile;
@override
Widget build(BuildContext context){
...other widgets
ProfilePictureCard(
isEditable: true, // because of this line the camera button is visible
imageFile: imageFile,
imageUrl: 'https://picsum.photos/id/237/200/300', // previous profile picture, will be replaced with selected image
)
}
_handleUpdate(){
print(imageFile.path);
}
}
Inside the CameraDialog other than the basic UI stuff for returning the selected file I have this:
void _captureImage(context) async {
final XFile? pickedFile =
await _picker.pickImage(source: ImageSource.camera);
if (pickedFile != null) {
final File file = File(pickedFile.path);
Navigator.of(context).pop(file);
}
}
But when I press update I am getting: Null check operator used on a null value
from the print(imageFile.path);
What is the reason for this issue, and how to solve this?
CodePudding user response:
You should use function to return your image instead of passing object,
class ProfilePictureCard extends StatefulWidget {
final bool? isSetProfilePage;
final bool? isEditable;
final Function(File file) handleUpdate;
final String? imageUrl;
ProfilePictureCard({
Key? key,
this.isSetProfilePage = false,
this.isEditable = false,
this.handleUpdate,
this.imageUrl,
})
usage
if (result != null) {
widget.handleUpdate(result);
}
In editing profile
class _EditProfilePage extends State<EditProfilePage {
File? imageFile;
@override
Widget build(BuildContext context){
...other widgets
ProfilePictureCard(
isEditable: true, // because of this line the camera button is visible
handleUpdate: _handleUpdate,
imageUrl: 'https://picsum.photos/id/237/200/300', // previous profile picture, will be replaced with selected image
)
}
_handleUpdate(File file){
print(file.path);
setState(() {
imageFile = file;
});
}
}