import 'package:f_cache/f_cache.dart'; import 'prelude.dart'; import '../utils.dart'; class AppNetImage extends StatefulWidget{ const AppNetImage({ super.key, required this.netImage, this.fit, this.onWidgetOk, this.width, this.height }); final NetImage netImage; final BoxFit? fit; final VoidCallback? onWidgetOk; final double? width; final double? height; @override State createState() { return _AppNetImageState(); } } CachedReaderImage cachedProvider(NetImage image){ return CachedReaderImage(image.md5Hex ?? '', image.readerBuilder); } class _AppNetImageState extends State{ late CachedReaderImage provider; @override void initState() { super.initState(); final image = widget.netImage; provider = cachedProvider(image); } @override void didUpdateWidget(covariant AppNetImage oldWidget) { super.didUpdateWidget(oldWidget); final image = widget.netImage; provider = cachedProvider(image); } @override Widget build(BuildContext context) { return Image( image: provider, loadingBuilder: ( BuildContext context, Widget child, ImageChunkEvent? loadingProgress){ if(loadingProgress!= null){ var p = 0.0; final all = loadingProgress.expectedTotalBytes?? 0; if(all > 0){ p = loadingProgress.cumulativeBytesLoaded.toDouble() / all.toDouble(); } return ImageLoading(value: p); }else{ return child; } }, errorBuilder: (ctx, e, trace){ warn('图片加载失败: ${widget.netImage.url} md5: ${widget.netImage.md5Hex}', e); return Container(color: Colors.white, child:const Center(child: Icon(Icons.broken_image_outlined))); }, width: widget.width, height: widget.height, fit: widget.fit, ); } } class ImageLoading extends StatelessWidget{ final double? value; const ImageLoading({ super.key, this.value }); @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration(color: Colors.grey.withAlpha(20)), child:Center( child: SizedBox( width: 48, height: 48, child: CircularProgressIndicator( value: value )), ) , ); } }