I wrote a function that gets a height of image in a cycle (array favorites contains Maps which contain url parameter and height parameter if loaded). The function also converts image's height in the size i actually need by formula with MediaQuery.of(context).size.width - 80 which is the width of images on screen. (Width of the screen minus 40 padding from each side).
This is the code of getting height function:
Future<void> getImageHeight(String url, index) async {
Image image = Image.network(url);
image.image
.resolve(const ImageConfiguration())
.addListener(ImageStreamListener((ImageInfo info, bool isSync) {
favorites[index]['height'] = info.image.height *
((MediaQuery.of(context).size.width - 80) / info.image.width);
setState(() {});
}));
}
And this is the code of image with placeholder (Container):
Container(
color: const Color(0xffE8E6EA),
height: favorites[index]['height'] == null || favorites[index
['height'].isNaN ? 0: favorites[index]['height'],
child: Image.network(
favorites[index]['url'],
width: double.infinity,
),
),
On first loading size of placeholder is still going to be zero, because it takes time to get height of them. But after few time (it usually takes about a second or less) setState is going to be called and images will not lag on scrolling. And if you are loading your images urls from database not all at once you'll need to rerun function to get height of newly added images.