fix(player): 收紧图片与快速切集资源占用
This commit is contained in:
1 parent
2fef7470e0
commit
80c962a95c
10 files changed
+281
-30
No files matched your search
@@ -5,6 +5,24 @@ import 'package:flutter/material.dart';
|
||||
import '../config/app_config.dart';
|
||||
import '../theme/app_colors.dart';
|
||||
|
||||
const int _minImageDecodePixels = 96;
|
||||
const int _maxImageDecodePixels = 2048;
|
||||
|
||||
/// 将布局逻辑尺寸换算成有限像素尺寸,兼顾小头像和全屏首帧。
|
||||
int resolveImageDecodePixels(double? logicalExtent, double devicePixelRatio) {
|
||||
final ratio = devicePixelRatio.isFinite && devicePixelRatio > 0
|
||||
? devicePixelRatio
|
||||
: 1.0;
|
||||
final extent =
|
||||
logicalExtent != null && logicalExtent.isFinite && logicalExtent > 0
|
||||
? logicalExtent
|
||||
: 120.0;
|
||||
return (extent * ratio)
|
||||
.ceil()
|
||||
.clamp(_minImageDecodePixels, _maxImageDecodePixels)
|
||||
.toInt();
|
||||
}
|
||||
|
||||
/// 封面图统一入口:后端给的是相对路径,这里补服务地址并处理加载失败。
|
||||
class RemoteImage extends StatelessWidget {
|
||||
const RemoteImage(
|
||||
@@ -17,6 +35,8 @@ class RemoteImage extends StatelessWidget {
|
||||
this.fallbackIconKey,
|
||||
this.fallbackAspectRatio,
|
||||
this.fallbackColor = AppColors.raised,
|
||||
this.decodeWidth,
|
||||
this.decodeHeight,
|
||||
});
|
||||
|
||||
final String path;
|
||||
@@ -27,21 +47,56 @@ class RemoteImage extends StatelessWidget {
|
||||
final Key? fallbackIconKey;
|
||||
final double? fallbackAspectRatio;
|
||||
final Color fallbackColor;
|
||||
final int? decodeWidth;
|
||||
final int? decodeHeight;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final url = AppConfig.mediaUrl(path);
|
||||
if (url.isEmpty) return _fallback(brand: showFallbackIcon);
|
||||
return Image.network(
|
||||
url,
|
||||
width: width,
|
||||
height: height,
|
||||
fit: fit,
|
||||
gaplessPlayback: true,
|
||||
errorBuilder: (_, _, _) => _fallback(brand: showFallbackIcon),
|
||||
frameBuilder: (context, child, frame, wasSynchronouslyLoaded) {
|
||||
if (wasSynchronouslyLoaded || frame != null) return child;
|
||||
return _fallback(brand: showFallbackIcon);
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final pixelRatio = MediaQuery.devicePixelRatioOf(context);
|
||||
final layoutWidth = constraints.hasBoundedWidth
|
||||
? constraints.maxWidth
|
||||
: width;
|
||||
final aspectRatio =
|
||||
fallbackAspectRatio != null &&
|
||||
fallbackAspectRatio!.isFinite &&
|
||||
fallbackAspectRatio! > 0
|
||||
? fallbackAspectRatio
|
||||
: null;
|
||||
final inferredHeight = constraints.hasBoundedHeight
|
||||
? constraints.maxHeight
|
||||
: height ??
|
||||
(layoutWidth != null && aspectRatio != null
|
||||
? layoutWidth / aspectRatio
|
||||
: null);
|
||||
final cacheWidth =
|
||||
decodeWidth ?? resolveImageDecodePixels(layoutWidth, pixelRatio);
|
||||
final cacheHeight =
|
||||
decodeHeight ??
|
||||
(inferredHeight == null
|
||||
? null
|
||||
: resolveImageDecodePixels(inferredHeight, pixelRatio));
|
||||
return Image.network(
|
||||
url,
|
||||
width: width,
|
||||
height: height,
|
||||
fit: fit,
|
||||
cacheWidth: cacheWidth
|
||||
.clamp(_minImageDecodePixels, _maxImageDecodePixels)
|
||||
.toInt(),
|
||||
cacheHeight: cacheHeight
|
||||
?.clamp(_minImageDecodePixels, _maxImageDecodePixels)
|
||||
.toInt(),
|
||||
gaplessPlayback: true,
|
||||
errorBuilder: (_, _, _) => _fallback(brand: showFallbackIcon),
|
||||
frameBuilder: (context, child, frame, wasSynchronouslyLoaded) {
|
||||
if (wasSynchronouslyLoaded || frame != null) return child;
|
||||
return _fallback(brand: showFallbackIcon);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user