app_net_image.dart 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import 'package:f_cache/f_cache.dart';
  2. import 'prelude.dart';
  3. import '../utils.dart';
  4. class AppNetImage extends StatefulWidget{
  5. const AppNetImage({
  6. super.key,
  7. required this.netImage,
  8. this.fit,
  9. this.onWidgetOk, this.width, this.height
  10. });
  11. final NetImage netImage;
  12. final BoxFit? fit;
  13. final VoidCallback? onWidgetOk;
  14. final double? width;
  15. final double? height;
  16. @override
  17. State<StatefulWidget> createState() {
  18. return _AppNetImageState();
  19. }
  20. }
  21. CachedReaderImage cachedProvider(NetImage image){
  22. return CachedReaderImage(image.md5Hex ?? '', image.readerBuilder);
  23. }
  24. class _AppNetImageState extends State<AppNetImage>{
  25. late CachedReaderImage provider;
  26. @override
  27. void initState() {
  28. super.initState();
  29. final image = widget.netImage;
  30. provider = cachedProvider(image);
  31. }
  32. @override
  33. void didUpdateWidget(covariant AppNetImage oldWidget) {
  34. super.didUpdateWidget(oldWidget);
  35. final image = widget.netImage;
  36. provider = cachedProvider(image);
  37. }
  38. @override
  39. Widget build(BuildContext context) {
  40. return Image(
  41. image: provider,
  42. loadingBuilder: (
  43. BuildContext context,
  44. Widget child,
  45. ImageChunkEvent? loadingProgress){
  46. if(loadingProgress!= null){
  47. var p = 0.0;
  48. final all = loadingProgress.expectedTotalBytes?? 0;
  49. if(all > 0){
  50. p = loadingProgress.cumulativeBytesLoaded.toDouble() / all.toDouble();
  51. }
  52. return ImageLoading(value: p);
  53. }else{
  54. return child;
  55. }
  56. },
  57. errorBuilder: (ctx, e, trace){
  58. warn('图片加载失败: ${widget.netImage.url} md5: ${widget.netImage.md5Hex}', e);
  59. return Container(color: Colors.white, child:const Center(child: Icon(Icons.broken_image_outlined)));
  60. },
  61. width: widget.width,
  62. height: widget.height,
  63. fit: widget.fit,
  64. );
  65. }
  66. }
  67. class ImageLoading extends StatelessWidget{
  68. final double? value;
  69. const ImageLoading({
  70. super.key,
  71. this.value
  72. });
  73. @override
  74. Widget build(BuildContext context) {
  75. return Container(
  76. decoration: BoxDecoration(color: Colors.grey.withAlpha(20)),
  77. child:Center(
  78. child: SizedBox(
  79. width: 48, height: 48,
  80. child: CircularProgressIndicator(
  81. value: value
  82. )),
  83. ) ,
  84. );
  85. }
  86. }