i am trying to make a listview with lots of images with different dimensions loaded from network. When I scroll down everything is okay, but when i am scrolling up, first images start to load changing the position of listview. I suppose I need to have a placeholder for images with height of image, but i dont know how to get their dimensions before them loaded. Or i need smth like listview that does not move because of smth upper loading.
CodePudding user response:
You can cover images with SizedBox.
SizedBox(height: 60, child: Image.network(""),)
CodePudding user response:
I wrote a function that runs in initState() and 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.