diff --git a/packages/flutter/lib/src/services/image_cache.dart b/packages/flutter/lib/src/services/image_cache.dart index 8826477eab0..a29db8ed57f 100644 --- a/packages/flutter/lib/src/services/image_cache.dart +++ b/packages/flutter/lib/src/services/image_cache.dart @@ -11,24 +11,44 @@ import 'fetch.dart'; import 'image_decoder.dart'; import 'image_resource.dart'; -Future _fetchImage(String url) async { - UrlResponse response = await fetchUrl(url); - if (response.statusCode >= 400) { - print("Failed (${response.statusCode}) to load image $url"); - return null; +/// Implements a way to retrieve an image, for example by fetching it from the network. +/// Also used as a key in the image cache. +abstract class ImageProvider { + Future loadImage(); +} + +class _UrlFetcher implements ImageProvider { + final String _url; + + _UrlFetcher(this._url); + + Future 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 { _ImageCache._(); - final Map _cache = new Map(); + final Map _cache = + new Map(); + + ImageResource loadProvider(ImageProvider provider) { + return _cache.putIfAbsent(provider, () { + return new ImageResource(provider.loadImage()); + }); + } ImageResource load(String url) { - return _cache.putIfAbsent(url, () { - return new ImageResource(_fetchImage(url)); - }); + return loadProvider(new _UrlFetcher(url)); } } diff --git a/packages/flutter/lib/src/widgets/basic.dart b/packages/flutter/lib/src/widgets/basic.dart index ea2f37b0b7c..74118d3b88d 100644 --- a/packages/flutter/lib/src/widgets/basic.dart +++ b/packages/flutter/lib/src/widgets/basic.dart @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:flutter/rendering.dart'; @@ -10,7 +9,6 @@ import 'package:flutter/services.dart'; import 'framework.dart'; -export 'dart:typed_data' show Uint8List; export 'package:flutter/rendering.dart' show BackgroundImage, BlockDirection, @@ -1180,10 +1178,10 @@ class DefaultAssetBundle extends InheritedWidget { bool updateShouldNotify(DefaultAssetBundle old) => bundle != old.bundle; } -class RawImage extends StatelessComponent { - RawImage({ +class AsyncImage extends StatelessComponent { + AsyncImage({ Key key, - this.bytes, + this.provider, this.width, this.height, this.colorFilter, @@ -1193,7 +1191,7 @@ class RawImage extends StatelessComponent { this.centerSlice }) : super(key: key); - final Uint8List bytes; + final ImageProvider provider; final double width; final double height; final ColorFilter colorFilter; @@ -1203,9 +1201,8 @@ class RawImage extends StatelessComponent { final Rect centerSlice; Widget build(BuildContext context) { - ImageResource image = new ImageResource(decodeImageFromList(bytes)); return new ImageListener( - image: image, + image: imageCache.loadProvider(provider), width: width, height: height, colorFilter: colorFilter,