Initial commit

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
谢宇宁
2026-11-05 10:38:11 +07:00
co-authored by Claude Opus 5.5
commit 2d26ea8f90
1071 changed files with 100151 additions and 0 deletions
@@ -0,0 +1,94 @@
import 'dart:ui';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:hjsq/assets_tool/images.dart';
import 'package:hjsq/hj_utils/screen.dart';
import 'package:hjsq/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),
);
}
}