Unverified Commit 5c381254 authored by stuartmorgan's avatar stuartmorgan Committed by GitHub

Wait for non-empty layout in platform view placeholder (#112402)

parent 4862a84b
...@@ -877,10 +877,10 @@ class _PlatformViewLinkState extends State<PlatformViewLink> { ...@@ -877,10 +877,10 @@ class _PlatformViewLinkState extends State<PlatformViewLink> {
return const SizedBox.expand(); return const SizedBox.expand();
} }
if (!_platformViewCreated) { if (!_platformViewCreated) {
// Depending on the implementation, the initial size can be used to size // Depending on the implementation, the first non-empty size can be used
// the platform view. // to size the platform view.
return _PlatformViewPlaceHolder(onLayout: (Size size) { return _PlatformViewPlaceHolder(onLayout: (Size size) {
if (controller.awaitingCreation) { if (controller.awaitingCreation && !size.isEmpty) {
controller.create(size: size); controller.create(size: size);
} }
}); });
......
...@@ -133,6 +133,9 @@ class FakeAndroidViewController implements AndroidViewController { ...@@ -133,6 +133,9 @@ class FakeAndroidViewController implements AndroidViewController {
@override @override
Future<void> create({Size? size}) async { Future<void> create({Size? size}) async {
assert(!_createCalledSuccessfully); assert(!_createCalledSuccessfully);
if (requiresSize && size != null) {
assert(!size.isEmpty);
}
_createCalledSuccessfully = size != null || !requiresSize; _createCalledSuccessfully = size != null || !requiresSize;
} }
......
...@@ -2502,6 +2502,48 @@ void main() { ...@@ -2502,6 +2502,48 @@ void main() {
}, },
); );
testWidgets(
'PlatformViewLink widget should not trigger creation with an empty size',
(WidgetTester tester) async {
late PlatformViewController controller;
final Widget widget = Center(child: SizedBox(
height: 0,
child: PlatformViewLink(
viewType: 'webview',
onCreatePlatformView: (PlatformViewCreationParams params) {
controller = FakeAndroidViewController(params.id, requiresSize: true);
controller.create();
// This test should be simulating one of the texture-based display
// modes, where `create` is a no-op when not provided a size, and
// creation is triggered via a later call to setSize, or to `create`
// with a size.
expect(controller.awaitingCreation, true);
return controller;
},
surfaceFactory: (BuildContext context, PlatformViewController controller) {
return PlatformViewSurface(
gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{},
controller: controller,
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
);
},
)
));
await tester.pumpWidget(widget);
expect(
tester.allWidgets.map((Widget widget) => widget.runtimeType.toString()).toList(),
equals(<String>['Center', 'SizedBox', 'PlatformViewLink', '_PlatformViewPlaceHolder']),
);
// 'create' should not have been called by PlatformViewLink, since its
// size is empty.
expect(controller.awaitingCreation, true);
},
);
testWidgets( testWidgets(
'PlatformViewLink calls create when needed for Android texture display modes', 'PlatformViewLink calls create when needed for Android texture display modes',
(WidgetTester tester) async { (WidgetTester tester) async {
...@@ -2541,6 +2583,9 @@ void main() { ...@@ -2541,6 +2583,9 @@ void main() {
equals(<String>['PlatformViewLink', '_PlatformViewPlaceHolder']), equals(<String>['PlatformViewLink', '_PlatformViewPlaceHolder']),
); );
// Layout should have triggered a create call. Simulate the callback
// that the real controller would make after creation.
expect(controller.awaitingCreation, false);
onPlatformViewCreatedCallBack(createdPlatformViewId); onPlatformViewCreatedCallBack(createdPlatformViewId);
await tester.pump(); await tester.pump();
...@@ -2551,7 +2596,6 @@ void main() { ...@@ -2551,7 +2596,6 @@ void main() {
); );
expect(createdPlatformViewId, currentViewId + 1); expect(createdPlatformViewId, currentViewId + 1);
expect(controller.awaitingCreation, false);
}, },
); );
......
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