diff --git a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md index 03f1539a069b..f5e40c814276 100644 --- a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md @@ -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 diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart index 3761dd2b99df..fe4aebf8d0ce 100644 --- a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart +++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart @@ -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( + params as AndroidWebViewWidgetCreationParams), viewType: 'plugins.flutter.io/webview', surfaceFactory: ( BuildContext context, diff --git a/packages/webview_flutter/webview_flutter_android/pubspec.yaml b/packages/webview_flutter/webview_flutter_android/pubspec.yaml index f56b5a6a9e7e..a58baa43e41f 100644 --- a/packages/webview_flutter/webview_flutter_android/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_android/pubspec.yaml @@ -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" diff --git a/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart b/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart index f3bdb63322e9..2809a40d885c 100644 --- a/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart +++ b/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart @@ -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'), + ), + ); + }); }); } diff --git a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md index 35b2b8fb0afa..c541e44515ce 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md @@ -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. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart index 5b87a39fe0bf..764ed11d6aa8 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart @@ -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( + params as WebKitWebViewWidgetCreationParams), viewType: 'plugins.flutter.io/webview', onPlatformViewCreated: (_) {}, layoutDirection: params.layoutDirection, diff --git a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml index 6e80a3964971..6eca6da5b7ad 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml @@ -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" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_widget_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_widget_test.dart index ae9ab6bd1d23..f7bd373b35bb 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_widget_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_widget_test.dart @@ -66,7 +66,14 @@ void main() { ); await tester.pumpAndSettle(); - expect(find.byKey(ObjectKey(webViewWidget.params)), findsOneWidget); + expect( + find.byKey( + ValueKey( + 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( + webViewWidget.params as WebKitWebViewWidgetCreationParams, + ), + ), + findsNothing, + ); + expect( + find.byKey( + ValueKey( + 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( + 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( + webViewWidget.params as WebKitWebViewWidgetCreationParams, + ), + ), + findsOneWidget, + ); }); }); }