Commit 04dfa0bf authored by Misha Dynin's avatar Misha Dynin

Merge pull request #483 from mishadynin/imagecache

Introduced ImageProvider for asynchronously loading images.
parents fd1dd7fa 7436dfd1
...@@ -11,25 +11,45 @@ import 'fetch.dart'; ...@@ -11,25 +11,45 @@ import 'fetch.dart';
import 'image_decoder.dart'; import 'image_decoder.dart';
import 'image_resource.dart'; import 'image_resource.dart';
Future<ui.Image> _fetchImage(String url) async { /// Implements a way to retrieve an image, for example by fetching it from the network.
UrlResponse response = await fetchUrl(url); /// Also used as a key in the image cache.
if (response.statusCode >= 400) { abstract class ImageProvider {
print("Failed (${response.statusCode}) to load image $url"); Future<ui.Image> loadImage();
return null; }
class _UrlFetcher implements ImageProvider {
final String _url;
_UrlFetcher(this._url);
Future<ui.Image> loadImage() async {
UrlResponse response = await fetchUrl(_url);
if (response.statusCode >= 400) {
print("Failed (${response.statusCode}) to load image $_url");
return null;
}
return await decodeImageFromDataPipe(response.body);
} }
return await decodeImageFromDataPipe(response.body);
bool operator ==(other) => other is _UrlFetcher && _url == other._url;
int get hashCode => _url.hashCode;
} }
class _ImageCache { class _ImageCache {
_ImageCache._(); _ImageCache._();
final Map<String, ImageResource> _cache = new Map<String, ImageResource>(); final Map<ImageProvider, ImageResource> _cache =
new Map<ImageProvider, ImageResource>();
ImageResource load(String url) { ImageResource loadProvider(ImageProvider provider) {
return _cache.putIfAbsent(url, () { return _cache.putIfAbsent(provider, () {
return new ImageResource(_fetchImage(url)); return new ImageResource(provider.loadImage());
}); });
} }
ImageResource load(String url) {
return loadProvider(new _UrlFetcher(url));
}
} }
final _ImageCache imageCache = new _ImageCache._(); final _ImageCache imageCache = new _ImageCache._();
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:typed_data';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
...@@ -10,7 +9,6 @@ import 'package:flutter/services.dart'; ...@@ -10,7 +9,6 @@ import 'package:flutter/services.dart';
import 'framework.dart'; import 'framework.dart';
export 'dart:typed_data' show Uint8List;
export 'package:flutter/rendering.dart' show export 'package:flutter/rendering.dart' show
BackgroundImage, BackgroundImage,
BlockDirection, BlockDirection,
...@@ -1180,10 +1178,10 @@ class DefaultAssetBundle extends InheritedWidget { ...@@ -1180,10 +1178,10 @@ class DefaultAssetBundle extends InheritedWidget {
bool updateShouldNotify(DefaultAssetBundle old) => bundle != old.bundle; bool updateShouldNotify(DefaultAssetBundle old) => bundle != old.bundle;
} }
class RawImage extends StatelessComponent { class AsyncImage extends StatelessComponent {
RawImage({ AsyncImage({
Key key, Key key,
this.bytes, this.provider,
this.width, this.width,
this.height, this.height,
this.colorFilter, this.colorFilter,
...@@ -1193,7 +1191,7 @@ class RawImage extends StatelessComponent { ...@@ -1193,7 +1191,7 @@ class RawImage extends StatelessComponent {
this.centerSlice this.centerSlice
}) : super(key: key); }) : super(key: key);
final Uint8List bytes; final ImageProvider provider;
final double width; final double width;
final double height; final double height;
final ColorFilter colorFilter; final ColorFilter colorFilter;
...@@ -1203,9 +1201,8 @@ class RawImage extends StatelessComponent { ...@@ -1203,9 +1201,8 @@ class RawImage extends StatelessComponent {
final Rect centerSlice; final Rect centerSlice;
Widget build(BuildContext context) { Widget build(BuildContext context) {
ImageResource image = new ImageResource(decodeImageFromList(bytes));
return new ImageListener( return new ImageListener(
image: image, image: imageCache.loadProvider(provider),
width: width, width: width,
height: height, height: height,
colorFilter: colorFilter, colorFilter: colorFilter,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment