Commit f6353b68 authored by Hans Muller's avatar Hans Muller Committed by GitHub

Image should handle InheritedWidget ancestor changes (#5656)

parent 22fe5db9
...@@ -193,6 +193,15 @@ class _ImageState extends State<Image> { ...@@ -193,6 +193,15 @@ class _ImageState extends State<Image> {
_resolveImage(); _resolveImage();
} }
@override
void deactivate() {
// If this image is activated again then force _imageStream to be recreated,
// in case the InheritedWidget ancestors it depends on have changed.
_imageStream?.removeListener(_handleImageChanged);
_imageStream = null;
super.deactivate();
}
@override @override
void dependenciesChanged() { void dependenciesChanged() {
_resolveImage(); _resolveImage();
...@@ -205,12 +214,6 @@ class _ImageState extends State<Image> { ...@@ -205,12 +214,6 @@ class _ImageState extends State<Image> {
super.reassemble(); super.reassemble();
} }
@override
void dispose() {
_imageStream.removeListener(_handleImageChanged);
super.dispose();
}
void _resolveImage() { void _resolveImage() {
final ImageStream oldImageStream = _imageStream; final ImageStream oldImageStream = _imageStream;
_imageStream = config.image.resolve(createLocalImageConfiguration( _imageStream = config.image.resolve(createLocalImageConfiguration(
......
...@@ -163,16 +163,146 @@ void main() { ...@@ -163,16 +163,146 @@ void main() {
expect(renderImage.image, isNotNull); expect(renderImage.image, isNotNull);
}); });
testWidgets('Verify ImageProvider configuration inheritance', (WidgetTester tester) async {
final GlobalKey mediaQueryKey1 = new GlobalKey(debugLabel: 'mediaQueryKey1');
final GlobalKey mediaQueryKey2 = new GlobalKey(debugLabel: 'mediaQueryKey2');
final GlobalKey imageKey = new GlobalKey(debugLabel: 'image');
final TestImageProvider imageProvider = new TestImageProvider();
// Of the two nested MediaQuery objects, the innermost one,
// mediaQuery2, should define the configuration of the imageProvider.
await tester.pumpWidget(
new MediaQuery(
key: mediaQueryKey1,
data: new MediaQueryData(
devicePixelRatio: 10.0,
padding: EdgeInsets.zero,
),
child: new MediaQuery(
key: mediaQueryKey2,
data: new MediaQueryData(
devicePixelRatio: 5.0,
padding: EdgeInsets.zero,
),
child: new Image(
key: imageKey,
image: imageProvider
),
)
)
);
expect(imageProvider._configuration.devicePixelRatio, 5.0);
// This is the same widget hierarchy as before except that the
// two MediaQuery objects have exchanged places. The imageProvider
// should be resolved again, with the new innermost MediaQuery.
await tester.pumpWidget(
new MediaQuery(
key: mediaQueryKey2,
data: new MediaQueryData(
devicePixelRatio: 5.0,
padding: EdgeInsets.zero,
),
child: new MediaQuery(
key: mediaQueryKey1,
data: new MediaQueryData(
devicePixelRatio: 10.0,
padding: EdgeInsets.zero,
),
child: new Image(
key: imageKey,
image: imageProvider
),
)
)
);
expect(imageProvider._configuration.devicePixelRatio, 10.0);
});
testWidgets('Verify ImageProvider configuration inheritance again', (WidgetTester tester) async {
final GlobalKey mediaQueryKey1 = new GlobalKey(debugLabel: 'mediaQueryKey1');
final GlobalKey mediaQueryKey2 = new GlobalKey(debugLabel: 'mediaQueryKey2');
final GlobalKey imageKey = new GlobalKey(debugLabel: 'image');
final TestImageProvider imageProvider = new TestImageProvider();
// This is just a variation on the previous test. In this version the location
// of the Image changes and the MediaQuery widgets do not.
await tester.pumpWidget(
new Row(
children: <Widget> [
new MediaQuery(
key: mediaQueryKey2,
data: new MediaQueryData(
devicePixelRatio: 5.0,
padding: EdgeInsets.zero,
),
child: new Image(
key: imageKey,
image: imageProvider
)
),
new MediaQuery(
key: mediaQueryKey1,
data: new MediaQueryData(
devicePixelRatio: 10.0,
padding: EdgeInsets.zero,
),
child: new Container(width: 100.0)
)
]
)
);
expect(imageProvider._configuration.devicePixelRatio, 5.0);
await tester.pumpWidget(
new Row(
children: <Widget> [
new MediaQuery(
key: mediaQueryKey2,
data: new MediaQueryData(
devicePixelRatio: 5.0,
padding: EdgeInsets.zero,
),
child: new Container(width: 100.0)
),
new MediaQuery(
key: mediaQueryKey1,
data: new MediaQueryData(
devicePixelRatio: 10.0,
padding: EdgeInsets.zero,
),
child: new Image(
key: imageKey,
image: imageProvider
)
)
]
)
);
expect(imageProvider._configuration.devicePixelRatio, 10.0);
});
} }
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;
@override @override
Future<TestImageProvider> obtainKey(ImageConfiguration configuration) { Future<TestImageProvider> obtainKey(ImageConfiguration configuration) {
return new SynchronousFuture<TestImageProvider>(this); return new SynchronousFuture<TestImageProvider>(this);
} }
@override
ImageStream resolve(ImageConfiguration configuration) {
_configuration = configuration;
return super.resolve(configuration);
}
@override @override
ImageStreamCompleter load(TestImageProvider key) => new OneFrameImageStreamCompleter(_completer.future); ImageStreamCompleter load(TestImageProvider key) => new OneFrameImageStreamCompleter(_completer.future);
......
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