Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/webview_flutter/webview_flutter_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 3.9.2

* Fixes bug where `PlatformWebViewWidget` doesn't rebuild when the controller or PlatformView
implementation flag changes.

## 3.9.1

* Adjusts SDK checks for better testability.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,25 @@ class AndroidWebViewWidgetCreationParams
///
/// Defaults to false.
final bool displayWithHybridComposition;

@override
int get hashCode => Object.hash(
controller,
layoutDirection,
displayWithHybridComposition,
platformViewsServiceProxy,
instanceManager,
);

@override
bool operator ==(Object other) {
return other is AndroidWebViewWidgetCreationParams &&
controller == other.controller &&
layoutDirection == other.layoutDirection &&
displayWithHybridComposition == other.displayWithHybridComposition &&
platformViewsServiceProxy == other.platformViewsServiceProxy &&
instanceManager == other.instanceManager;
}
}

/// An implementation of [PlatformWebViewWidget] with the Android WebView API.
Expand All @@ -763,7 +782,9 @@ class AndroidWebViewWidget extends PlatformWebViewWidget {
@override
Widget build(BuildContext context) {
return PlatformViewLink(
key: _androidParams.key,
// Setting a default key using `params` ensures the `PlatformViewLink`
// recreates the PlatformView when changes are made.
key: _androidParams.key ?? ObjectKey(params),
viewType: 'plugins.flutter.io/webview',
surfaceFactory: (
BuildContext context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.1
version: 3.9.2

environment:
sdk: ">=2.18.0 <4.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1216,5 +1216,68 @@ void main() {
),
);
});

testWidgets('PlatformView is recreated when the controller changes',
(WidgetTester tester) async {
final MockPlatformViewsServiceProxy mockPlatformViewsService =
MockPlatformViewsServiceProxy();

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: createControllerWithMocks(),
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: createControllerWithMocks(),
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'),
),
);
});
});
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 3.7.1

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

## 3.7.0

* Adds support for `WebResouceError.url`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,21 @@ class WebKitWebViewWidgetCreationParams
// Maintains instances used to communicate with the native objects they
// represent.
final InstanceManager _instanceManager;

@override
int get hashCode => Object.hash(
controller,
layoutDirection,
_instanceManager,
);

@override
bool operator ==(Object other) {
return other is WebKitWebViewWidgetCreationParams &&
controller == other.controller &&
layoutDirection == other.layoutDirection &&
_instanceManager == other._instanceManager;
}
}

/// An implementation of [PlatformWebViewWidget] with the WebKit api.
Expand All @@ -651,7 +666,9 @@ class WebKitWebViewWidget extends PlatformWebViewWidget {
@override
Widget build(BuildContext context) {
return UiKitView(
key: _webKitParams.key,
// Setting a default key using `params` ensures the `UIKitView` recreates
// the PlatformView when changes are made.
key: _webKitParams.key ?? ObjectKey(params),
viewType: 'plugins.flutter.io/webview',
onPlatformViewCreated: (_) {},
layoutDirection: params.layoutDirection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.0
version: 3.7.1

environment:
sdk: ">=2.18.0 <4.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,37 +24,8 @@ void main() {
onWeakReferenceRemoved: (_) {},
);

final WebKitWebViewController controller = WebKitWebViewController(
WebKitWebViewControllerCreationParams(
webKitProxy: WebKitProxy(createWebView: (
WKWebViewConfiguration configuration, {
void Function(
String keyPath,
NSObject object,
Map<NSKeyValueChangeKey, Object?> change,
)? observeValue,
InstanceManager? instanceManager,
}) {
final WKWebView webView = WKWebView.detached(
instanceManager: testInstanceManager,
);
testInstanceManager.addDartCreatedInstance(webView);
return webView;
}, createWebViewConfiguration: ({InstanceManager? instanceManager}) {
return MockWKWebViewConfiguration();
}, createUIDelegate: ({
dynamic onCreateWebView,
dynamic requestMediaCapturePermission,
InstanceManager? instanceManager,
}) {
final MockWKUIDelegate mockWKUIDelegate = MockWKUIDelegate();
when(mockWKUIDelegate.copy()).thenReturn(MockWKUIDelegate());

testInstanceManager.addDartCreatedInstance(mockWKUIDelegate);
return mockWKUIDelegate;
}),
),
);
final WebKitWebViewController controller =
createTestWebViewController(testInstanceManager);

final WebKitWebViewWidget widget = WebKitWebViewWidget(
WebKitWebViewWidgetCreationParams(
Expand All @@ -71,5 +42,86 @@ void main() {
expect(find.byType(UiKitView), findsOneWidget);
expect(find.byKey(const Key('keyValue')), findsOneWidget);
});

testWidgets('Key of the PlatformView changes when the controller changes',
(WidgetTester tester) async {
final InstanceManager testInstanceManager = InstanceManager(
onWeakReferenceRemoved: (_) {},
);

// Pump WebViewWidget with first controller.
final WebKitWebViewController controller1 =
createTestWebViewController(testInstanceManager);
final WebKitWebViewWidget webViewWidget = WebKitWebViewWidget(
WebKitWebViewWidgetCreationParams(
controller: controller1,
instanceManager: testInstanceManager,
),
);

await tester.pumpWidget(
Builder(
builder: (BuildContext context) => webViewWidget.build(context),
),
);
await tester.pumpAndSettle();

expect(find.byKey(ObjectKey(webViewWidget.params)), findsOneWidget);

// Pump WebViewWidget with second controller.
final WebKitWebViewController controller2 =
createTestWebViewController(testInstanceManager);
final WebKitWebViewWidget webViewWidget2 = WebKitWebViewWidget(
WebKitWebViewWidgetCreationParams(
controller: controller2,
instanceManager: testInstanceManager,
),
);

await tester.pumpWidget(
Builder(
builder: (BuildContext context) => webViewWidget2.build(context),
),
);
await tester.pumpAndSettle();

expect(find.byKey(ObjectKey(webViewWidget2.params)), findsOneWidget);
});
});
}

WebKitWebViewController createTestWebViewController(
InstanceManager testInstanceManager,
) {
return WebKitWebViewController(
WebKitWebViewControllerCreationParams(
webKitProxy: WebKitProxy(createWebView: (
WKWebViewConfiguration configuration, {
void Function(
String keyPath,
NSObject object,
Map<NSKeyValueChangeKey, Object?> change,
)? observeValue,
InstanceManager? instanceManager,
}) {
final WKWebView webView = WKWebView.detached(
instanceManager: testInstanceManager,
);
testInstanceManager.addDartCreatedInstance(webView);
return webView;
}, createWebViewConfiguration: ({InstanceManager? instanceManager}) {
return MockWKWebViewConfiguration();
}, createUIDelegate: ({
dynamic onCreateWebView,
dynamic requestMediaCapturePermission,
InstanceManager? instanceManager,
}) {
final MockWKUIDelegate mockWKUIDelegate = MockWKUIDelegate();
when(mockWKUIDelegate.copy()).thenReturn(MockWKUIDelegate());

testInstanceManager.addDartCreatedInstance(mockWKUIDelegate);
return mockWKUIDelegate;
}),
),
);
}