import 'dart:ui'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'dart:ui' as ui; import 'package:network_image_cached/src/http_request.dart'; class CachedNetworkImageProvider extends ImageProvider { final String imageUrl; final int count; final BoxFit fit; final double? width; final double? height; final Widget? placeholder; final Widget? errorWidget; final bool cached; final String? cachkey; final Widget? loadwidget; const CachedNetworkImageProvider({ required this.imageUrl, required this.cachkey, required this.fit, this.count = 10, this.height, this.width, this.errorWidget, this.placeholder, this.cached = true, this.loadwidget = const CircularProgressIndicator(), }); @override ImageStreamCompleter loadImage( CachedNetworkImageProvider key, ImageDecoderCallback decode, ) { // 1. Создаём Future, который загрузит и декодирует изображение // 2. Возвращаем ImageStreamCompleter, который управляет потоком загрузки return MultiFrameImageStreamCompleter( codec: _loadAndDecodeImage(decode), scale: 1.0, informationCollector: () => [ DiagnosticsProperty( 'Image provider', key, showName: false, ), ], ); } // Вспомогательный метод: загружает байты и декодирует в ui.Image Future _loadAndDecodeImage(ImageDecoderCallback decode) async { try { // 1. Отправляем HTTP‑запрос HttpGetImage httpGetImage = HttpGetImage(url: imageUrl, count: count); // 2. Декодируем байты в ui.Image Uint8List img = await httpGetImage.getDataObjectIsolate(); final decodedImage = await decode( await ImmutableBuffer.fromUint8List(img), ); return decodedImage; } catch (e) { // Если ошибка — бросаем исключение (будет обработано в Image widget) throw Exception('Failed to load image: $e'); } } @override Future obtainKey( ImageConfiguration configuration, ) { return SynchronousFuture(this); } }