Skip to content

Commit 175ff56

Browse files
[webview_flutter_android][webview_flutter_wkwebview] Fixes widget rebuild bug caused by key type (#4667)
It looks like the wrong key was used in #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 flutter/flutter#131697 Fixes flutter/flutter#132143
1 parent 881c1f5 commit 175ff56

File tree

8 files changed

+165
-6
lines changed

8 files changed

+165
-6
lines changed

packages/webview_flutter/webview_flutter_android/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 3.9.3
2+
3+
* Fixes bug where the `PlatformWebViewWidget` was rebuilt unnecessarily.
4+
15
## 3.9.2
26

37
* Fixes bug where `PlatformWebViewWidget` doesn't rebuild when the controller or PlatformView

packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,9 @@ class AndroidWebViewWidget extends PlatformWebViewWidget {
784784
return PlatformViewLink(
785785
// Setting a default key using `params` ensures the `PlatformViewLink`
786786
// recreates the PlatformView when changes are made.
787-
key: _androidParams.key ?? ObjectKey(params),
787+
key: _androidParams.key ??
788+
ValueKey<AndroidWebViewWidgetCreationParams>(
789+
params as AndroidWebViewWidgetCreationParams),
788790
viewType: 'plugins.flutter.io/webview',
789791
surfaceFactory: (
790792
BuildContext context,

packages/webview_flutter/webview_flutter_android/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: webview_flutter_android
22
description: A Flutter plugin that provides a WebView widget on Android.
33
repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_android
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
5-
version: 3.9.2
5+
version: 3.9.3
66

77
environment:
88
sdk: ">=2.18.0 <4.0.0"

packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,5 +1279,71 @@ void main() {
12791279
),
12801280
);
12811281
});
1282+
1283+
testWidgets(
1284+
'PlatformView does not rebuild when creation params stay the same',
1285+
(WidgetTester tester) async {
1286+
final MockPlatformViewsServiceProxy mockPlatformViewsService =
1287+
MockPlatformViewsServiceProxy();
1288+
1289+
final AndroidWebViewController controller = createControllerWithMocks();
1290+
1291+
when(
1292+
mockPlatformViewsService.initSurfaceAndroidView(
1293+
id: anyNamed('id'),
1294+
viewType: anyNamed('viewType'),
1295+
layoutDirection: anyNamed('layoutDirection'),
1296+
creationParams: anyNamed('creationParams'),
1297+
creationParamsCodec: anyNamed('creationParamsCodec'),
1298+
onFocus: anyNamed('onFocus'),
1299+
),
1300+
).thenReturn(MockSurfaceAndroidViewController());
1301+
1302+
await tester.pumpWidget(Builder(
1303+
builder: (BuildContext context) {
1304+
return AndroidWebViewWidget(
1305+
AndroidWebViewWidgetCreationParams(
1306+
controller: controller,
1307+
platformViewsServiceProxy: mockPlatformViewsService,
1308+
),
1309+
).build(context);
1310+
},
1311+
));
1312+
await tester.pumpAndSettle();
1313+
1314+
verify(
1315+
mockPlatformViewsService.initSurfaceAndroidView(
1316+
id: anyNamed('id'),
1317+
viewType: anyNamed('viewType'),
1318+
layoutDirection: anyNamed('layoutDirection'),
1319+
creationParams: anyNamed('creationParams'),
1320+
creationParamsCodec: anyNamed('creationParamsCodec'),
1321+
onFocus: anyNamed('onFocus'),
1322+
),
1323+
);
1324+
1325+
await tester.pumpWidget(Builder(
1326+
builder: (BuildContext context) {
1327+
return AndroidWebViewWidget(
1328+
AndroidWebViewWidgetCreationParams(
1329+
controller: controller,
1330+
platformViewsServiceProxy: mockPlatformViewsService,
1331+
),
1332+
).build(context);
1333+
},
1334+
));
1335+
await tester.pumpAndSettle();
1336+
1337+
verifyNever(
1338+
mockPlatformViewsService.initSurfaceAndroidView(
1339+
id: anyNamed('id'),
1340+
viewType: anyNamed('viewType'),
1341+
layoutDirection: anyNamed('layoutDirection'),
1342+
creationParams: anyNamed('creationParams'),
1343+
creationParamsCodec: anyNamed('creationParamsCodec'),
1344+
onFocus: anyNamed('onFocus'),
1345+
),
1346+
);
1347+
});
12821348
});
12831349
}

packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 3.7.3
2+
3+
* Fixes bug where the `PlatformWebViewWidget` was rebuilt unnecessarily.
4+
15
## 3.7.2
26

37
* Fixes bug where `PlatformWebViewWidget` doesn't rebuild when the controller changes.

packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,9 @@ class WebKitWebViewWidget extends PlatformWebViewWidget {
668668
return UiKitView(
669669
// Setting a default key using `params` ensures the `UIKitView` recreates
670670
// the PlatformView when changes are made.
671-
key: _webKitParams.key ?? ObjectKey(params),
671+
key: _webKitParams.key ??
672+
ValueKey<WebKitWebViewWidgetCreationParams>(
673+
params as WebKitWebViewWidgetCreationParams),
672674
viewType: 'plugins.flutter.io/webview',
673675
onPlatformViewCreated: (_) {},
674676
layoutDirection: params.layoutDirection,

packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: webview_flutter_wkwebview
22
description: A Flutter plugin that provides a WebView widget based on Apple's WKWebView control.
33
repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_wkwebview
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
5-
version: 3.7.2
5+
version: 3.7.3
66

77
environment:
88
sdk: ">=2.18.0 <4.0.0"

packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_widget_test.dart

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,14 @@ void main() {
6666
);
6767
await tester.pumpAndSettle();
6868

69-
expect(find.byKey(ObjectKey(webViewWidget.params)), findsOneWidget);
69+
expect(
70+
find.byKey(
71+
ValueKey<WebKitWebViewWidgetCreationParams>(
72+
webViewWidget.params as WebKitWebViewWidgetCreationParams,
73+
),
74+
),
75+
findsOneWidget,
76+
);
7077

7178
// Pump WebViewWidget with second controller.
7279
final WebKitWebViewController controller2 =
@@ -85,7 +92,81 @@ void main() {
8592
);
8693
await tester.pumpAndSettle();
8794

88-
expect(find.byKey(ObjectKey(webViewWidget2.params)), findsOneWidget);
95+
expect(webViewWidget.params != webViewWidget2.params, isTrue);
96+
expect(
97+
find.byKey(
98+
ValueKey<WebKitWebViewWidgetCreationParams>(
99+
webViewWidget.params as WebKitWebViewWidgetCreationParams,
100+
),
101+
),
102+
findsNothing,
103+
);
104+
expect(
105+
find.byKey(
106+
ValueKey<WebKitWebViewWidgetCreationParams>(
107+
webViewWidget2.params as WebKitWebViewWidgetCreationParams,
108+
),
109+
),
110+
findsOneWidget,
111+
);
112+
});
113+
114+
testWidgets(
115+
'Key of the PlatformView is the same when the creation params are equal',
116+
(WidgetTester tester) async {
117+
final InstanceManager testInstanceManager = InstanceManager(
118+
onWeakReferenceRemoved: (_) {},
119+
);
120+
121+
final WebKitWebViewController controller =
122+
createTestWebViewController(testInstanceManager);
123+
124+
final WebKitWebViewWidget webViewWidget = WebKitWebViewWidget(
125+
WebKitWebViewWidgetCreationParams(
126+
controller: controller,
127+
instanceManager: testInstanceManager,
128+
),
129+
);
130+
131+
await tester.pumpWidget(
132+
Builder(
133+
builder: (BuildContext context) => webViewWidget.build(context),
134+
),
135+
);
136+
await tester.pumpAndSettle();
137+
138+
expect(
139+
find.byKey(
140+
ValueKey<WebKitWebViewWidgetCreationParams>(
141+
webViewWidget.params as WebKitWebViewWidgetCreationParams,
142+
),
143+
),
144+
findsOneWidget,
145+
);
146+
147+
final WebKitWebViewWidget webViewWidget2 = WebKitWebViewWidget(
148+
WebKitWebViewWidgetCreationParams(
149+
controller: controller,
150+
instanceManager: testInstanceManager,
151+
),
152+
);
153+
154+
await tester.pumpWidget(
155+
Builder(
156+
builder: (BuildContext context) => webViewWidget2.build(context),
157+
),
158+
);
159+
await tester.pumpAndSettle();
160+
161+
// Can find the new widget with the key of the first widget.
162+
expect(
163+
find.byKey(
164+
ValueKey<WebKitWebViewWidgetCreationParams>(
165+
webViewWidget.params as WebKitWebViewWidgetCreationParams,
166+
),
167+
),
168+
findsOneWidget,
169+
);
89170
});
90171
});
91172
}

0 commit comments

Comments
 (0)