feat(media): 图片占位改为纯色块并去掉扫光

This commit is contained in:
Zhou Weidong committed 2026-11-02 14:44:28 +08:00
1 parent 613147c20c
commit 7f65fe4d48
20 files changed
+48 -291

No files matched your search

+11 -43
View File
@@ -1,10 +1,10 @@
// Author: fruit.com.cn
// 职责:统一网络图片入口,补服务地址,并在加载中/失败时显示纯色占位块。
import 'package:flutter/material.dart';
import '../config/app_config.dart';
import '../theme/app_colors.dart';
import 'image_placeholder_shimmer.dart';
const int _minImageDecodePixels = 96;
const int _maxImageDecodePixels = 2048;
@@ -32,8 +32,6 @@ class RemoteImage extends StatelessWidget {
this.width,
this.height,
this.fit = BoxFit.cover,
this.showFallbackIcon = false,
this.fallbackIconKey,
this.fallbackAspectRatio,
this.fallbackColor = AppColors.raised,
this.fallbackWidget,
@@ -45,12 +43,10 @@ class RemoteImage extends StatelessWidget {
final double? width;
final double? height;
final BoxFit fit;
final bool showFallbackIcon;
final Key? fallbackIconKey;
final double? fallbackAspectRatio;
final Color fallbackColor;
/// 自定义兜底:地址为空、加载中、加载失败时都显示它(优先于 [fallbackColor])。
/// 自定义占位:地址为空、加载中、加载失败时都显示它(优先于 [fallbackColor])。
final Widget? fallbackWidget;
final int? decodeWidth;
final int? decodeHeight;
@@ -58,7 +54,7 @@ class RemoteImage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final url = AppConfig.mediaUrl(path);
if (url.isEmpty) return _fallback(brand: showFallbackIcon);
if (url.isEmpty) return _fallback();
return LayoutBuilder(
builder: (context, constraints) {
final pixelRatio = MediaQuery.devicePixelRatioOf(context);
@@ -100,51 +96,23 @@ class RemoteImage extends StatelessWidget {
?.clamp(_minImageDecodePixels, _maxImageDecodePixels)
.toInt(),
gaplessPlayback: true,
errorBuilder: (_, _, _) => _fallback(brand: showFallbackIcon),
errorBuilder: (_, _, _) => _fallback(),
frameBuilder: (context, child, frame, wasSynchronouslyLoaded) {
if (wasSynchronouslyLoaded || frame != null) return child;
return _loadingFallback();
return _fallback();
},
);
},
);
}
Widget _loadingFallback() {
Widget _fallback() {
final custom = fallbackWidget;
if (custom != null) return custom;
return ImagePlaceholderShimmer(child: _fallback(brand: showFallbackIcon));
}
Widget _fallback({required bool brand}) {
final custom = fallbackWidget;
if (custom != null) return custom;
final mark = brand
? LayoutBuilder(
builder: (context, constraints) {
final width = constraints.maxWidth.isFinite
? constraints.maxWidth
: 120.0;
return Center(
child: Image.asset(
'assets/icon/splash_logo.png',
key: fallbackIconKey,
width: width * 0.72,
fit: BoxFit.contain,
),
);
},
)
: null;
final fallback = Container(
width: width,
height: height,
color: brand ? AppColors.mediaBlack : fallbackColor,
alignment: Alignment.center,
child: mark,
);
final content = custom != null
? SizedBox(width: width, height: height, child: custom)
: Container(width: width, height: height, color: fallbackColor);
final ratio = fallbackAspectRatio;
if (ratio == null) return fallback;
return AspectRatio(aspectRatio: ratio, child: fallback);
if (ratio == null) return content;
return AspectRatio(aspectRatio: ratio, child: content);
}
}