[webview_flutter_android][webview_flutter_wkwebview] Fixes widget rebuild bug caused by key type (#4667)

It looks like the wrong key was used in https://github.com/flutter/packages/pull/4533. The `ObjectKey` uses `identical` for comparison while `ValueKey` uses `==`, which is what was intended. This just switches the key type on both platforms.

Fixes https://github.com/flutter/flutter/issues/131697
Fixes https://github.com/flutter/flutter/issues/132143
This commit is contained in:
Maurice Parrish
2023-08-09 16:36:45 -04:00
committed by GitHub
parent 881c1f552d
commit 175ff5603b
8 changed files with 165 additions and 6 deletions

View File

@ -1,3 +1,7 @@
## 3.9.3
* Fixes bug where the `PlatformWebViewWidget` was rebuilt unnecessarily.
## 3.9.2
* Fixes bug where `PlatformWebViewWidget` doesn't rebuild when the controller or PlatformView

View File

@ -784,7 +784,9 @@ class AndroidWebViewWidget extends PlatformWebViewWidget {
return PlatformViewLink(
// Setting a default key using `params` ensures the `PlatformViewLink`
// recreates the PlatformView when changes are made.
key: _androidParams.key ?? ObjectKey(params),
key: _androidParams.key ??
ValueKey<AndroidWebViewWidgetCreationParams>(
params as AndroidWebViewWidgetCreationParams),
viewType: 'plugins.flutter.io/webview',
surfaceFactory: (
BuildContext context,

View File

@ -2,7 +2,7 @@ name: webview_flutter_android
description: A Flutter plugin that provides a WebView widget on Android.
repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_android
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
version: 3.9.2
version: 3.9.3
environment:
sdk: ">=2.18.0 <4.0.0"

View File

@ -1279,5 +1279,71 @@ void main() {
),
);
});
testWidgets(
'PlatformView does not rebuild when creation params stay the same',
(WidgetTester tester) async {
final MockPlatformViewsServiceProxy mockPlatformViewsService =
MockPlatformViewsServiceProxy();
final AndroidWebViewController controller = createControllerWithMocks();
when(
mockPlatformViewsService.initSurfaceAndroidView(
id: anyNamed('id'),
viewType: anyNamed('viewType'),
layoutDirection: anyNamed('layoutDirection'),
creationParams: anyNamed('creationParams'),
creationParamsCodec: anyNamed('creationParamsCodec'),
onFocus: anyNamed('onFocus'),
),
).thenReturn(MockSurfaceAndroidViewController());
await tester.pumpWidget(Builder(
builder: (BuildContext context) {
return AndroidWebViewWidget(
AndroidWebViewWidgetCreationParams(
controller: controller,
platformViewsServiceProxy: mockPlatformViewsService,
),
).build(context);
},
));
await tester.pumpAndSettle();
verify(
mockPlatformViewsService.initSurfaceAndroidView(
id: anyNamed('id'),
viewType: anyNamed('viewType'),
layoutDirection: anyNamed('layoutDirection'),
creationParams: anyNamed('creationParams'),
creationParamsCodec: anyNamed('creationParamsCodec'),
onFocus: anyNamed('onFocus'),
),
);
await tester.pumpWidget(Builder(
builder: (BuildContext context) {
return AndroidWebViewWidget(
AndroidWebViewWidgetCreationParams(
controller: controller,
platformViewsServiceProxy: mockPlatformViewsService,
),
).build(context);
},
));
await tester.pumpAndSettle();
verifyNever(
mockPlatformViewsService.initSurfaceAndroidView(
id: anyNamed('id'),
viewType: anyNamed('viewType'),
layoutDirection: anyNamed('layoutDirection'),
creationParams: anyNamed('creationParams'),
creationParamsCodec: anyNamed('creationParamsCodec'),
onFocus: anyNamed('onFocus'),
),
);
});
});
}

View File

@ -1,3 +1,7 @@
## 3.7.3
* Fixes bug where the `PlatformWebViewWidget` was rebuilt unnecessarily.
## 3.7.2
* Fixes bug where `PlatformWebViewWidget` doesn't rebuild when the controller changes.

View File

@ -668,7 +668,9 @@ class WebKitWebViewWidget extends PlatformWebViewWidget {
return UiKitView(
// Setting a default key using `params` ensures the `UIKitView` recreates
// the PlatformView when changes are made.
key: _webKitParams.key ?? ObjectKey(params),
key: _webKitParams.key ??
ValueKey<WebKitWebViewWidgetCreationParams>(
params as WebKitWebViewWidgetCreationParams),
viewType: 'plugins.flutter.io/webview',
onPlatformViewCreated: (_) {},
layoutDirection: params.layoutDirection,

View File

@ -2,7 +2,7 @@ name: webview_flutter_wkwebview
description: A Flutter plugin that provides a WebView widget based on Apple's WKWebView control.
repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_wkwebview
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
version: 3.7.2
version: 3.7.3
environment:
sdk: ">=2.18.0 <4.0.0"

View File

@ -66,7 +66,14 @@ void main() {
);
await tester.pumpAndSettle();
expect(find.byKey(ObjectKey(webViewWidget.params)), findsOneWidget);
expect(
find.byKey(
ValueKey<WebKitWebViewWidgetCreationParams>(
webViewWidget.params as WebKitWebViewWidgetCreationParams,
),
),
findsOneWidget,
);
// Pump WebViewWidget with second controller.
final WebKitWebViewController controller2 =
@ -85,7 +92,81 @@ void main() {
);
await tester.pumpAndSettle();
expect(find.byKey(ObjectKey(webViewWidget2.params)), findsOneWidget);
expect(webViewWidget.params != webViewWidget2.params, isTrue);
expect(
find.byKey(
ValueKey<WebKitWebViewWidgetCreationParams>(
webViewWidget.params as WebKitWebViewWidgetCreationParams,
),
),
findsNothing,
);
expect(
find.byKey(
ValueKey<WebKitWebViewWidgetCreationParams>(
webViewWidget2.params as WebKitWebViewWidgetCreationParams,
),
),
findsOneWidget,
);
});
testWidgets(
'Key of the PlatformView is the same when the creation params are equal',
(WidgetTester tester) async {
final InstanceManager testInstanceManager = InstanceManager(
onWeakReferenceRemoved: (_) {},
);
final WebKitWebViewController controller =
createTestWebViewController(testInstanceManager);
final WebKitWebViewWidget webViewWidget = WebKitWebViewWidget(
WebKitWebViewWidgetCreationParams(
controller: controller,
instanceManager: testInstanceManager,
),
);
await tester.pumpWidget(
Builder(
builder: (BuildContext context) => webViewWidget.build(context),
),
);
await tester.pumpAndSettle();
expect(
find.byKey(
ValueKey<WebKitWebViewWidgetCreationParams>(
webViewWidget.params as WebKitWebViewWidgetCreationParams,
),
),
findsOneWidget,
);
final WebKitWebViewWidget webViewWidget2 = WebKitWebViewWidget(
WebKitWebViewWidgetCreationParams(
controller: controller,
instanceManager: testInstanceManager,
),
);
await tester.pumpWidget(
Builder(
builder: (BuildContext context) => webViewWidget2.build(context),
),
);
await tester.pumpAndSettle();
// Can find the new widget with the key of the first widget.
expect(
find.byKey(
ValueKey<WebKitWebViewWidgetCreationParams>(
webViewWidget.params as WebKitWebViewWidgetCreationParams,
),
),
findsOneWidget,
);
});
});
}