import 'dart:ui'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:wydj/assets_tool/images.dart'; import 'package:wydj/hj_utils/screen.dart'; import 'package:wydj/tools_base/cache/image_cache_manager.dart'; class NetworkImageLoader extends StatelessWidget { final String? imageUrl; final double? width; final double? height; final BoxFit fit; final Alignment alignment; final double borderRadius; final BorderRadius? imgBorderRadius; final bool blur; //高斯模糊 final bool encrypt; //是否需要加密 final Widget? placeHolderWidget; final bool isResizeImage; //是否需要根据组件大小压缩 const NetworkImageLoader({ super.key, required this.imageUrl, this.borderRadius = 8, this.imgBorderRadius, this.height, this.fit = BoxFit.cover, this.width, this.blur = false, this.alignment = Alignment.center, this.encrypt = true, this.placeHolderWidget, this.isResizeImage = true, }); @override Widget build(BuildContext context) { return LayoutBuilder(builder: (context, cons) { Widget image = CachedNetworkImage( alignment: alignment, imageUrl: imageUrl ?? '', width: width, height: height, fit: fit, memCacheWidth: _memCacheWidth(cons), // 默认 FilterQuality.low 用廉价 bilinear,iOS retina(dpr=3) 上肉眼可见的模糊 // medium 是质量/性能平衡点,high 会卡列表滚动 filterQuality: FilterQuality.medium, cacheManager: encrypt ? ImageCacheManager() : null, placeholder: (context, url) => _placeholder(), errorWidget: (context, url, err) => _placeholder(), fadeInCurve: Curves.linear, fadeOutCurve: Curves.linear, ); final radius = imgBorderRadius ?? BorderRadius.circular(borderRadius); if (borderRadius != 0) image = ClipRRect(borderRadius: radius, child: image); //模糊会溢出边界,外面再裁一层 if (blur) { image = ClipRRect( borderRadius: radius, child: ImageFiltered( imageFilter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), child: image), ); } return image; }); } //resize的宽度 int _memCacheWidth(BoxConstraints cons) { final dpr = screen.devicePixelRatio; if (!isResizeImage) return (screen.screenWidth * dpr).toInt(); //约束无限时用屏幕宽兜底,避免退化成按原图解码(图片过载) final w = (cons.maxWidth == double.infinity || cons.maxWidth.isNaN) ? screen.screenWidth : cons.maxWidth; return (w * dpr).toInt(); } Widget _placeholder() { if (placeHolderWidget != null) return placeHolderWidget!; return Container( padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2), decoration: const BoxDecoration(color: Color(0xff151E2D)), alignment: Alignment.center, child: Image.asset('place_holder_logo.webp'.commonImgPath, width: 100, height: 35), ); } }