I would like to have some insight into what is the best way to go to show images from assets and imagePicked images (stored in db) in the same gridView? I am using a Photo model class with different variables to store the images, assetPath to store assetimages and fileName to store images from db (these are converted to Image.memory through a utillity method). The problem as I see it is that i Store the images in the same List to be able to display them but this raises issues when some images are base64 and others are assetPath (String). whats best practice regarding this?
Here is my test code. I am here trying to check if the photo contains an assetPath and if so its an asset image otherwise its an imagepicked image and then I use utility method and display it as an Image.memory.
When I test the app on a physical device it shows the asset images fine but the database (imagepicked ) files are just empty squares (as it should be because of base64 I suppose).
I can also mention that the imagepicking and database utility methods are working fine so I choose to not include them here. The main issue is as mentioned best practice for showing both asset and imagepicked from database files in the same gridview.
gridView:
gridview2() {
String image1 = ('images/lake.jpg');
String image2 = ('images/flower1.png');
Photo photo1 = Photo(id: 0, fileName: image1);
Photo photo2 = Photo(id: 0, fileName: image2);
images!.add(photo1);
images!.add(photo2);
return Padding(
padding: const EdgeInsets.all(5.0),
child: GridView.builder(
itemCount: images!.length,
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
crossAxisSpacing: 20,
mainAxisSpacing: 20),
itemBuilder: (BuildContext ctx, int index) {
return Container(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
//todo we need a check if String is database base64 or asset path??
image: images![index].fileName!.isNotEmpty
? Image.asset(images![index].fileName!).image
: Utility.imageFromBase64String(
images![index].fileName!)
.image),
));
}));
}
Scaffold:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Center(child: Text('ImagePicker Database test')),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: () {
setState(() {
pickImagesFromGallery();
});
},
),
],
),
body: Column(
children: <Widget>[
Flexible(child: gridview2()),
],
),
);
}
}
initState function:
void initState() {
super.initState();
images = [];
dbHelper = DBHelper();
refreshImages();
}
RefreshImage function:
refreshImages() {
dbHelper!.getPhotos().then((imgs) {
setState(() {
//Clears list
images!.clear();
//Add all images from imgs (database) to images list
images!.addAll(imgs);
});
});
}
Solution I used in the Gridview2 function:
return Container(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: images![index].assetPath != null
? Image.asset(images![index].assetPath!).image
: Utility.imageFromBase64String(
images![index].fileName!)
.image),
));
From physical phone when loaded and added one picked file (becomes empty):
2
Answers
To have a separate field for the imageAsset and also do a check for nulls instead of "isNotEmpty" check seems to have fixed the issue. I have no idéa though if this is a good solution, probably not but it works! I will edit the code to reflect the working code. Thank you Banjoe for the suggestion with separate fields!
I would adjust your Photo model to have separate fields for assetPath and base64String. This way you can know for sure what the image data looks like.
I would also double check your Utility.imageFromBase64String() function to make sure that works by itself.