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> {
_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
void dependenciesChanged() {
_resolveImage();
......@@ -205,12 +214,6 @@ class _ImageState extends State<Image> {
super.reassemble();
}
@override
void dispose() {
_imageStream.removeListener(_handleImageChanged);
super.dispose();
}
void _resolveImage() {
final ImageStream oldImageStream = _imageStream;
_imageStream = config.image.resolve(createLocalImageConfiguration(
......
......@@ -163,16 +163,146 @@ void main() {
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> {
final Completer<ImageInfo> _completer = new Completer<ImageInfo>();
ImageConfiguration _configuration;
@override
Future<TestImageProvider> obtainKey(ImageConfiguration configuration) {
return new SynchronousFuture<TestImageProvider>(this);
}
@override
ImageStream resolve(ImageConfiguration configuration) {
_configuration = configuration;
return super.resolve(configuration);
}
@override
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