Files
huangguo_android/lib/tools_base/widget/net_image_widget.dart
T
2026-09-15 15:44:13 +07:00

122 lines
3.7 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:ui';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:hgdj/assets_tool/images.dart';
import 'package:hgdj/hj_utils/screen.dart';
import 'package:hgdj/tools_base/cache/image_cache_manager.dart';
class NetworkImageLoader extends StatelessWidget {
final double borderRadius;
final BorderRadius? imgBorderRadius;
final String? imageUrl;
final double? width;
final double? height;
final BoxFit fit;
final double? placeHolderH;
final double? placeHolderW;
final bool blur; //高斯模糊
final Alignment alignment;
final bool encrypt; //是否需要加密
final Widget? placeHolderWidget;
final int? loadWidth; // 服务端根据宽度等比例压缩
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.placeHolderH,
this.placeHolderW,
this.alignment = Alignment.center,
this.encrypt = true,
this.placeHolderWidget,
this.loadWidth,
this.isResizeImage = true,
});
bool get isGif => imageUrl?.contains(".gif") ?? false;
String get realImgUrl {
if (imageUrl == null) return "";
return imageUrl!;
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, cons) {
final imageWidget = CachedNetworkImage(
alignment: alignment,
imageUrl: realImgUrl,
width: width,
height: height,
fit: fit,
memCacheWidth: memCacheWidth(cons),
// 默认 FilterQuality.low 用廉价 bilineariOS retina(dpr=3) 上肉眼可见的模糊
// medium 是质量/性能平衡点,high 会卡列表滚动
filterQuality: FilterQuality.medium,
cacheManager: encrypt ? ImageCacheManager() : null,
placeholder: (context, url) => _buildPlaceHolder(),
errorWidget: (context, url, err) => _buildPlaceHolder(),
fadeInCurve: Curves.linear,
fadeOutCurve: Curves.linear,
);
final clip = borderRadius == 0
? imageWidget
: ClipRRect(
borderRadius:
imgBorderRadius ?? BorderRadius.circular(borderRadius),
child: imageWidget,
);
final backdrop = blur
? ClipRRect(
borderRadius:
imgBorderRadius ?? BorderRadius.circular(borderRadius),
child: ImageFiltered(
imageFilter: ImageFilter.blur(
sigmaX: 5,
sigmaY: 5,
),
child: clip,
),
)
: clip;
return backdrop;
});
}
//resize的宽度
int? memCacheWidth(BoxConstraints cons) {
final dpr = screen.devicePixelRatio;
if (isResizeImage == true) {
//约束无限时用屏幕宽兜底,避免退化成按原图解码(图片过载)
final w = (cons.maxWidth == double.infinity || cons.maxWidth.isNaN)
? screen.screenWidth
: cons.maxWidth;
return (w * dpr).toInt();
} else {
return loadWidth != null
? loadWidth!
: (screen.screenWidth * dpr).toInt();
}
}
_buildPlaceHolder() {
if (placeHolderWidget != null) return placeHolderWidget;
return Container(
padding: EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration(color: Color(0xff343434)),
alignment: Alignment.center,
child: Image.asset(
'place_holder_logo.webp'.commonImgPath,
width: placeHolderW ?? 136,
height: placeHolderW ?? 96,
),
);
}
}