import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:http/http.dart' as http;
// 使用CachedNetworkImageProvider作为图片提供者
class CachedNetworkImage extends StatelessWidget {
final String imageUrl;
final double width;
final double height;
final BoxFit fit;
const CachedNetworkImage({
Key key,
@required this.imageUrl,
this.width,
this.height,
this.fit,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Image(
image: CachedNetworkImageProvider(imageUrl: imageUrl),
width: width,
height: height,
fit: fit,
);
}
}
class CachedNetworkImageProvider extends ImageProvider<CachedNetworkImageProvider> {
final String imageUrl;
final http.Client httpClient;
CachedNetworkImageProvider({
@required this.imageUrl,
this.httpClient = http.Client(),
});
@override
Future<CachedNetworkImageProvider> obtainKey(ImageConfiguration configuration) {
return SynchronousFuture<CachedNetworkImageProvider>(this);
}
@override
ImageStreamCompleter load(CachedNetworkImageProvider key) {
final PaintingBinding binding = PaintingBinding.instance;
final ImageStreamCompleter completer = ImageStreamCompleter();
// 内存缓存逻辑
if (binding.imageCache.putIfAbsent(
key, () => completer.loader, onError: binding.imageCache.onError) != null) {
return completer;
}
// 文件缓存逻辑
final File tempFile = File(key.imageUrl);
if (tempFile.existsSync()) {
completer.setImage(binding.instantiateImageCodec, tempFile.readAsBytesSync());
} else {
httpClient
.get(Uri.parse(key.imageUrl))
.then((http.Response response) => response.bodyBytes)
.then((Uint8List bytes) {
if (completer.isCompleted) {
return;
}
// 将图片数据写入文件缓存
tempFile.writeAsBytes(bytes).then((_) {
binding.instantiateImageCodec(bytes).then((codec) {
if (completer.isCompleted) {
return;
}
completer.setImage(codec);
}, onError: binding.imageC
评论已关闭