| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- import 'dart:ui' as ui;
- import 'dart:ui';
- import 'package:flutter/foundation.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter_bloc/flutter_bloc.dart';
- import 'package:network_image_cached/src/http_request.dart';
- import 'src/bloc/cashed_image_bloc.dart'
- show
- CashedImageBloc,
- CashedImageGetErrorState,
- CashedImageGetState,
- CashedImageState,
- GetStartImageEvent;
- class CachedNetworkImageWidget extends StatelessWidget {
- 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 CachedNetworkImageWidget({
- super.key,
- 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
- Widget build(BuildContext context) {
- return BlocProvider(
- create: (context) => CashedImageBloc()
- ..add(
- GetStartImageEvent(
- url: imageUrl,
- cached: cached,
- count: count,
- cachkey: cachkey,
- ),
- ),
- child: Builder(
- builder: (context) {
- return BlocBuilder<CashedImageBloc, CashedImageState>(
- builder: (context, state) {
- if (state is CashedImageGetErrorState) {
- return SizedBox(
- width: width,
- height: height,
- child: errorWidget ?? Center(child: Icon(Icons.error)),
- );
- }
- if (state is CashedImageGetState) {
- return Image.memory(
- state.bytes,
- fit: fit,
- width: width,
- height: height,
- );
- }
- return SizedBox(
- width: width,
- height: height,
- child:
- placeholder ?? Center(child: CircularProgressIndicator()),
- );
- },
- );
- },
- ),
- );
- }
- }
- class CachedNetworkImageProvider
- extends ImageProvider<CachedNetworkImageProvider> {
- 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: () => <DiagnosticsNode>[
- DiagnosticsProperty<CachedNetworkImageProvider>(
- 'Image provider',
- key,
- showName: false,
- ),
- ],
- );
- }
- // Вспомогательный метод: загружает байты и декодирует в ui.Image
- Future<ui.Codec> _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<CachedNetworkImageProvider> obtainKey(
- ImageConfiguration configuration,
- ) {
- return SynchronousFuture<CachedNetworkImageProvider>(this);
- }
- }
|