An API that prefetches an image into the cache (#11471)
This commit is contained in:
parent
3d5afb5a81
commit
c80d2482f9
@ -2,6 +2,7 @@
|
|||||||
// 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:async';
|
||||||
import 'dart:io' show File;
|
import 'dart:io' show File;
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
@ -44,6 +45,34 @@ ImageConfiguration createLocalImageConfiguration(BuildContext context, { Size si
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Prefetches an image into the image cache.
|
||||||
|
///
|
||||||
|
/// Returns a [Future] that will complete when the first image yielded by the
|
||||||
|
/// [ImageProvider] is available.
|
||||||
|
///
|
||||||
|
/// If the image is later used by an [Image] or [BoxDecoration] or [FadeInImage],
|
||||||
|
/// it will probably be loaded faster. The consumer of the image does not need
|
||||||
|
/// to use the same [ImageProvider] instance. The [ImageCache] will find the image
|
||||||
|
/// as long as both images share the same key.
|
||||||
|
///
|
||||||
|
/// The [BuildContext] and [Size] are used to select an image configuration
|
||||||
|
/// (see [createLocalImageConfiguration]).
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [ImageCache], which holds images that may be reused.
|
||||||
|
Future<Null> precacheImage(ImageProvider provider, BuildContext context, { Size size }) {
|
||||||
|
final ImageConfiguration config = createLocalImageConfiguration(context, size: size);
|
||||||
|
final Completer<Null> completer = new Completer<Null>();
|
||||||
|
final ImageStream stream = provider.resolve(config);
|
||||||
|
void listener(ImageInfo image, bool sync) {
|
||||||
|
completer.complete();
|
||||||
|
}
|
||||||
|
stream.addListener(listener);
|
||||||
|
completer.future.then((Null _) { stream.removeListener(listener); });
|
||||||
|
return completer.future;
|
||||||
|
}
|
||||||
|
|
||||||
/// A widget that displays an image.
|
/// A widget that displays an image.
|
||||||
///
|
///
|
||||||
/// Several constructors are provided for the various ways that an image can be
|
/// Several constructors are provided for the various ways that an image can be
|
||||||
|
@ -196,7 +196,7 @@ void main() {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(imageProvider._configuration.devicePixelRatio, 5.0);
|
expect(imageProvider._lastResolvedConfiguration.devicePixelRatio, 5.0);
|
||||||
|
|
||||||
// This is the same widget hierarchy as before except that the
|
// This is the same widget hierarchy as before except that the
|
||||||
// two MediaQuery objects have exchanged places. The imageProvider
|
// two MediaQuery objects have exchanged places. The imageProvider
|
||||||
@ -222,7 +222,7 @@ void main() {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(imageProvider._configuration.devicePixelRatio, 10.0);
|
expect(imageProvider._lastResolvedConfiguration.devicePixelRatio, 10.0);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Verify ImageProvider configuration inheritance again', (WidgetTester tester) async {
|
testWidgets('Verify ImageProvider configuration inheritance again', (WidgetTester tester) async {
|
||||||
@ -259,7 +259,7 @@ void main() {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(imageProvider._configuration.devicePixelRatio, 5.0);
|
expect(imageProvider._lastResolvedConfiguration.devicePixelRatio, 5.0);
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
new Row(
|
new Row(
|
||||||
@ -287,7 +287,7 @@ void main() {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(imageProvider._configuration.devicePixelRatio, 10.0);
|
expect(imageProvider._lastResolvedConfiguration.devicePixelRatio, 10.0);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Verify Image stops listening to ImageStream', (WidgetTester tester) async {
|
testWidgets('Verify Image stops listening to ImageStream', (WidgetTester tester) async {
|
||||||
@ -318,11 +318,33 @@ void main() {
|
|||||||
expect(renderer.color, const Color(0xFF00FF00));
|
expect(renderer.color, const Color(0xFF00FF00));
|
||||||
expect(renderer.colorBlendMode, BlendMode.clear);
|
expect(renderer.colorBlendMode, BlendMode.clear);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('Precache', (WidgetTester tester) async {
|
||||||
|
final TestImageProvider provider = new TestImageProvider();
|
||||||
|
Future<Null> precache;
|
||||||
|
await tester.pumpWidget(
|
||||||
|
new Builder(
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
precache = precacheImage(provider, context);
|
||||||
|
return new Container();
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
provider.complete();
|
||||||
|
await precache;
|
||||||
|
expect(provider._lastResolvedConfiguration, isNotNull);
|
||||||
|
|
||||||
|
// Check that a second resolve of the same image is synchronous.
|
||||||
|
final ImageStream stream = provider.resolve(provider._lastResolvedConfiguration);
|
||||||
|
bool isSync;
|
||||||
|
stream.addListener((ImageInfo image, bool sync) { isSync = sync; });
|
||||||
|
expect(isSync, isTrue);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestImageProvider extends ImageProvider<TestImageProvider> {
|
class TestImageProvider extends ImageProvider<TestImageProvider> {
|
||||||
final Completer<ImageInfo> _completer = new Completer<ImageInfo>();
|
final Completer<ImageInfo> _completer = new Completer<ImageInfo>();
|
||||||
ImageConfiguration _configuration;
|
ImageConfiguration _lastResolvedConfiguration;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<TestImageProvider> obtainKey(ImageConfiguration configuration) {
|
Future<TestImageProvider> obtainKey(ImageConfiguration configuration) {
|
||||||
@ -331,7 +353,7 @@ class TestImageProvider extends ImageProvider<TestImageProvider> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
ImageStream resolve(ImageConfiguration configuration) {
|
ImageStream resolve(ImageConfiguration configuration) {
|
||||||
_configuration = configuration;
|
_lastResolvedConfiguration = configuration;
|
||||||
return super.resolve(configuration);
|
return super.resolve(configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user