|
1 | | -import 'package:flutter/widgets.dart'; |
| 1 | +import 'package:flutter/cupertino.dart'; |
| 2 | +import 'package:loading_gifs/loading_gifs.dart'; |
| 3 | +import 'package:minimal/utils/utils_image.dart'; |
2 | 4 |
|
3 | | -class ImageFixedWidth extends StatelessWidget { |
4 | | - final String image; |
| 5 | +class ImageFixedWidth extends StatefulWidget { |
| 6 | + static const String name = 'ImageFixedWidth'; |
| 7 | + |
| 8 | + final String imageUrl; |
5 | 9 | final double width; |
6 | | - final double? imageRatio; |
7 | | - final String placeholder; |
| 10 | + final double imageRatio; |
| 11 | + |
| 12 | + const ImageFixedWidth( |
| 13 | + {Key? key, |
| 14 | + required this.imageUrl, |
| 15 | + required this.width, |
| 16 | + this.imageRatio = 1}) |
| 17 | + : super(key: key); |
| 18 | + |
| 19 | + @override |
| 20 | + _ImageFixedWidthState createState() => _ImageFixedWidthState(); |
| 21 | +} |
8 | 22 |
|
9 | | - const ImageFixedWidth(this.image, this.width, |
10 | | - {this.imageRatio = 1.618, this.placeholder = ""}); |
| 23 | +class _ImageFixedWidthState extends State<ImageFixedWidth> { |
| 24 | + bool imagesLoaded = false; |
| 25 | + bool preloadedImages = false; |
| 26 | + |
| 27 | + @override |
| 28 | + void didUpdateWidget(ImageFixedWidth oldWidget) { |
| 29 | + super.didUpdateWidget(oldWidget); |
| 30 | + if (oldWidget.imageUrl != widget.imageUrl) { |
| 31 | + preloadedImages = false; |
| 32 | + imagesLoaded = false; |
| 33 | + } |
| 34 | + } |
11 | 35 |
|
12 | 36 | @override |
13 | 37 | Widget build(BuildContext context) { |
14 | | - final double height = imageRatio == null ? width : imageRatio! * width; |
15 | | - |
16 | | - return FadeInImage.assetNetwork( |
17 | | - image: image, |
18 | | - placeholder: placeholder, |
19 | | - width: width, |
20 | | - height: height, |
21 | | - fit: BoxFit.cover, |
22 | | - fadeOutDuration: const Duration(milliseconds: 100), |
23 | | - fadeInDuration: const Duration(milliseconds: 200), |
24 | | - ); |
| 38 | + if (!preloadedImages) { |
| 39 | + preloadedImages = true; |
| 40 | + ImageUtils.preloadNetworkImages(context, [ |
| 41 | + widget.imageUrl, |
| 42 | + ]).whenComplete(() { |
| 43 | + if (mounted) { |
| 44 | + imagesLoaded = true; |
| 45 | + setState(() {}); |
| 46 | + } |
| 47 | + }); |
| 48 | + } |
| 49 | + |
| 50 | + return LayoutBuilder(builder: (context, constraints) { |
| 51 | + double width = constraints.maxWidth; |
| 52 | + double height = (width * widget.imageRatio).roundToDouble(); |
| 53 | + return SizedBox( |
| 54 | + width: width, |
| 55 | + height: height, |
| 56 | + child: Stack( |
| 57 | + children: [ |
| 58 | + if (imagesLoaded == false) |
| 59 | + const Center( |
| 60 | + child: Center(child: CupertinoActivityIndicator(radius: 16)), |
| 61 | + ), |
| 62 | + FadeInImage.assetNetwork( |
| 63 | + image: widget.imageUrl, |
| 64 | + placeholder: placeholderEmpty, |
| 65 | + width: width, |
| 66 | + height: height, |
| 67 | + fit: BoxFit.cover, |
| 68 | + fadeOutDuration: const Duration(milliseconds: 100), |
| 69 | + fadeInDuration: const Duration(milliseconds: 200), |
| 70 | + ), |
| 71 | + ], |
| 72 | + ), |
| 73 | + ); |
| 74 | + }); |
25 | 75 | } |
26 | 76 | } |
0 commit comments