Skip to content

Commit 840a049

Browse files
[webview_flutter] Copies app-facing implementation of webview_flutter from v4_webview (flutter#6856)
* copy code from v4_webview * version bump and readme update * work towards better readme * improvements * more readme progress * improvements * fix main and update more readme * excerpt changes and more 3.0 diffs * cookie manager update * remove packages from exclude list * lint * better range * isForMainFrame * load page after waiting for widget * fix integration tests * improve readme a bit * collapse changelong. update platform-specific wording. include in excerpt tests * use platform implementation packages * include missing exports * PR comments * correct spelling * interface dev dependency * move other usage above migration * remove interface classes
1 parent 32dcbf3 commit 840a049

35 files changed

+5528
-3333
lines changed

packages/webview_flutter/webview_flutter/CHANGELOG.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
## NEXT
1+
## 4.0.0
22

3-
* Updates code for `no_leading_underscores_for_local_identifiers` lint.
4-
* Updates minimum Flutter version to 2.10.
5-
* Fixes avoid_redundant_argument_values lint warnings and minor typos.
6-
* Ignores unnecessary import warnings in preparation for [upcoming Flutter changes](https://github.com/flutter/flutter/pull/104231).
3+
* **BREAKING CHANGE** Updates implementation to use the `2.0.0` release of
4+
`webview_flutter_platform_interface`. See `Usage` section in the README for updated usage. See
5+
`Migrating from 3.0 to 4.0` section in the README for details on migrating to this version.
6+
* Updates minimum Flutter version to 3.0.0.
7+
* Updates code for new analysis options.
78
* Updates references to the obsolete master branch.
8-
* Fixes typo from lowercase to uppercase.
99

1010
## 3.0.4
1111

Original file line numberDiff line numberDiff line change
@@ -1,41 +1,73 @@
11
# WebView for Flutter
22

3+
<?code-excerpt path-base="excerpts/packages/webview_flutter_example"?>
4+
35
[![pub package](https://img.shields.io/pub/v/webview_flutter.svg)](https://pub.dev/packages/webview_flutter)
46

57
A Flutter plugin that provides a WebView widget.
68

7-
On iOS the WebView widget is backed by a [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview);
9+
On iOS the WebView widget is backed by a [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview).
810
On Android the WebView widget is backed by a [WebView](https://developer.android.com/reference/android/webkit/WebView).
911

1012
| | Android | iOS |
1113
|-------------|----------------|------|
1214
| **Support** | SDK 19+ or 20+ | 9.0+ |
1315

1416
## Usage
15-
Add `webview_flutter` as a [dependency in your pubspec.yaml file](https://flutter.dev/docs/development/platform-integration/platform-channels). If you are targeting Android, make sure to read the *Android Platform Views* section below to choose the platform view mode that best suits your needs.
16-
17-
You can now include a WebView widget in your widget tree. See the
18-
[WebView](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebView-class.html)
19-
widget's Dartdoc for more details on how to use the widget.
17+
Add `webview_flutter` as a [dependency in your pubspec.yaml file](https://pub.dev/packages/webview_flutter/install).
18+
19+
You can now display a WebView by:
20+
21+
1. Instantiating a [WebViewController](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewController-class.html).
22+
23+
<?code-excerpt "simple_example.dart (webview_controller)"?>
24+
```dart
25+
controller = WebViewController()
26+
..setJavaScriptMode(JavaScriptMode.unrestricted)
27+
..setBackgroundColor(const Color(0x00000000))
28+
..setNavigationDelegate(
29+
NavigationDelegate(
30+
onProgress: (int progress) {
31+
// Update loading bar.
32+
},
33+
onPageStarted: (String url) {},
34+
onPageFinished: (String url) {},
35+
onWebResourceError: (WebResourceError error) {},
36+
onNavigationRequest: (NavigationRequest request) {
37+
if (request.url.startsWith('https://www.youtube.com/')) {
38+
return NavigationDecision.prevent;
39+
}
40+
return NavigationDecision.navigate;
41+
},
42+
),
43+
)
44+
..loadRequest(Uri.parse('https://flutter.dev'));
45+
```
2046

21-
## Android Platform Views
22-
This plugin uses
23-
[Platform Views](https://flutter.dev/docs/development/platform-integration/platform-views) to embed
24-
the Android’s webview within the Flutter app. It supports two modes:
25-
*hybrid composition* (the current default) and *virtual display*.
47+
2. Passing the controller to a [WebViewWidget](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewWidget-class.html).
2648

27-
Here are some points to consider when choosing between the two:
49+
<?code-excerpt "simple_example.dart (webview_widget)"?>
50+
```dart
51+
@override
52+
Widget build(BuildContext context) {
53+
return Scaffold(
54+
appBar: AppBar(title: const Text('Flutter Simple Example')),
55+
body: WebViewWidget(controller: controller),
56+
);
57+
}
58+
```
2859

29-
* *Hybrid composition* has built-in keyboard support while *virtual display* has multiple
30-
[keyboard issues](https://github.com/flutter/flutter/issues?q=is%3Aopen+label%3Avd-only+label%3A%22p%3A+webview-keyboard%22).
31-
* *Hybrid composition* requires Android SDK 19+ while *virtual display* requires Android SDK 20+.
32-
* *Hybrid composition* and *virtual display* have different
33-
[performance tradeoffs](https://flutter.dev/docs/development/platform-integration/platform-views#performance).
60+
See the Dartdocs for [WebViewController](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewController-class.html)
61+
and [WebViewWidget](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewWidget-class.html)
62+
for more details.
3463

64+
### Android Platform Views
3565

36-
### Using Hybrid Composition
66+
This plugin uses
67+
[Platform Views](https://flutter.dev/docs/development/platform-integration/platform-views) to embed
68+
the Android’s WebView within the Flutter app.
3769

38-
The mode is currently enabled by default. You should however make sure to set the correct `minSdkVersion` in `android/app/build.gradle` if it was previously lower than 19:
70+
You should however make sure to set the correct `minSdkVersion` in `android/app/build.gradle` if it was previously lower than 19:
3971

4072
```groovy
4173
android {
@@ -45,47 +77,67 @@ android {
4577
}
4678
```
4779

48-
### Using Virtual displays
80+
### Platform-Specific Features
4981

50-
1. Set the correct `minSdkVersion` in `android/app/build.gradle` (if it was previously lower than 20):
82+
Many classes have a subclass or an underlying implementation that provides access to platform-specific
83+
features.
5184

52-
```groovy
53-
android {
54-
defaultConfig {
55-
minSdkVersion 20
56-
}
57-
}
58-
```
85+
To access platform-specific features, start by adding the platform implementation packages to your
86+
app or package:
5987

60-
2. Set `WebView.platform = AndroidWebView();` in `initState()`.
61-
For example:
88+
* **Android**: [webview_flutter_android](https://pub.dev/packages/webview_flutter_android/install)
89+
* **iOS**: [webview_flutter_wkwebview](https://pub.dev/packages/webview_flutter_wkwebview/install)
6290

63-
```dart
64-
import 'dart:io';
91+
Next, add the imports of the implementation packages to your app or package:
6592

66-
import 'package:webview_flutter/webview_flutter.dart';
93+
<?code-excerpt "main.dart (platform_imports)"?>
94+
```dart
95+
// Import for Android features.
96+
import 'package:webview_flutter_android/webview_flutter_android.dart';
97+
// Import for iOS features.
98+
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
99+
```
67100

68-
class WebViewExample extends StatefulWidget {
69-
@override
70-
WebViewExampleState createState() => WebViewExampleState();
71-
}
101+
Now, additional features can be accessed through the platform implementations. Classes
102+
`WebViewController`, `WebViewWidget`, `NavigationDelegate`, and `WebViewCookieManager` pass their
103+
functionality to a class provided by the current platform. Below are a couple of ways to access
104+
additional functionality provided by the platform and is followed by an example.
105+
106+
1. Pass a creation params class provided by a platform implementation to a `fromPlatformCreationParams`
107+
constructor (e.g. `WebViewController.fromPlatformCreationParams`,
108+
`WebViewWidget.fromPlatformCreationParams`, etc.).
109+
2. Call methods on a platform implementation of a class by using the `platform` field (e.g.
110+
`WebViewController.platform`, `WebViewWidget.platform`, etc.).
111+
112+
Below is an example of setting additional iOS and Android parameters on the `WebViewController`.
113+
114+
<?code-excerpt "main.dart (platform_features)"?>
115+
```dart
116+
late final PlatformWebViewControllerCreationParams params;
117+
if (WebViewPlatform.instance is WebKitWebViewPlatform) {
118+
params = WebKitWebViewControllerCreationParams(
119+
allowsInlineMediaPlayback: true,
120+
mediaTypesRequiringUserAction: const <PlaybackMediaTypes>{},
121+
);
122+
} else {
123+
params = const PlatformWebViewControllerCreationParams();
124+
}
72125
73-
class WebViewExampleState extends State<WebViewExample> {
74-
@override
75-
void initState() {
76-
super.initState();
77-
// Enable virtual display.
78-
if (Platform.isAndroid) WebView.platform = AndroidWebView();
79-
}
80-
81-
@override
82-
Widget build(BuildContext context) {
83-
return WebView(
84-
initialUrl: 'https://flutter.dev',
85-
);
86-
}
87-
}
88-
```
126+
final WebViewController controller =
127+
WebViewController.fromPlatformCreationParams(params);
128+
// ···
129+
if (controller.platform is AndroidWebViewController) {
130+
AndroidWebViewController.enableDebugging(true);
131+
(controller.platform as AndroidWebViewController)
132+
.setMediaPlaybackRequiresUserGesture(false);
133+
}
134+
```
135+
136+
See https://pub.dev/documentation/webview_flutter_android/latest/webview_flutter_android/webview_flutter_android-library.html
137+
for more details on Android features.
138+
139+
See https://pub.dev/documentation/webview_flutter_wkwebview/latest/webview_flutter_wkwebview/webview_flutter_wkwebview-library.html
140+
for more details on iOS features.
89141

90142
### Enable Material Components for Android
91143

@@ -95,4 +147,76 @@ follow the steps described in the [Enabling Material Components instructions](ht
95147
### Setting custom headers on POST requests
96148

97149
Currently, setting custom headers when making a post request with the WebViewController's `loadRequest` method is not supported on Android.
98-
If you require this functionality, a workaround is to make the request manually, and then load the response data using `loadHTMLString` instead.
150+
If you require this functionality, a workaround is to make the request manually, and then load the response data using `loadHtmlString` instead.
151+
152+
## Migrating from 3.0 to 4.0
153+
154+
### Instantiating WebViewController
155+
156+
In version 3.0 and below, `WebViewController` could only be retrieved in a callback after the
157+
`WebView` was added to the widget tree. Now, `WebViewController` must be instantiated and can be
158+
used before it is added to the widget tree. See `Usage` section above for an example.
159+
160+
### Replacing WebView Functionality
161+
162+
The `WebView` class has been removed and its functionality has been split into `WebViewController`
163+
and `WebViewWidget`.
164+
165+
`WebViewController` handles all functionality that is associated with the underlying web view
166+
provided by each platform. (e.g., loading a url, setting the background color of the underlying
167+
platform view, or clearing the cache).
168+
169+
`WebViewWidget` takes a `WebViewController` and handles all Flutter widget related functionality
170+
(e.g., layout direction, gesture recognizers).
171+
172+
See the Dartdocs for [WebViewController](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewController-class.html)
173+
and [WebViewWidget](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewWidget-class.html)
174+
for more details.
175+
176+
### PlatformView Implementation on Android
177+
178+
The PlatformView implementation for Android is currently no longer configurable. It uses Texture
179+
Layer Hybrid Composition on versions 23+ and automatically fallbacks to Hybrid Composition for
180+
version 19-23. See https://github.com/flutter/flutter/issues/108106 for progress on manually
181+
switching to Hybrid Composition on versions 23+.
182+
183+
### API Changes
184+
185+
Below is a non-exhaustive list of changes to the API:
186+
187+
* `WebViewController.clearCache` no longer clears local storage. Please use
188+
`WebViewController.clearLocalStorage`.
189+
* `WebViewController.clearCache` no longer reloads the page.
190+
* `WebViewController.loadUrl` has been removed. Please use `WebViewController.loadRequest`.
191+
* `WebViewController.evaluateJavascript` has been removed. Please use
192+
`WebViewController.runJavaScript` or `WebViewController.runJavaScriptReturningResult`.
193+
* `WebViewController.getScrollX` and `WebViewController.getScrollY` have been removed and have
194+
been replaced by `WebViewController.getScrollPosition`.
195+
* `WebViewController.runJavaScriptReturningResult` now returns an `Object` and not a `String`. This
196+
will attempt to return a `bool` or `num` if the return value can be parsed.
197+
* `CookieManager` is replaced by `WebViewCookieManager`.
198+
* `NavigationDelegate.onWebResourceError` callback includes errors that are not from the main frame.
199+
Use the `WebResourceError.isForMainFrame` field to filter errors.
200+
* The following fields from `WebView` have been moved to `NavigationDelegate`. They can be added to
201+
a WebView with `WebViewController.setNavigationDelegate`.
202+
* `WebView.navigationDelegate` -> `NavigationDelegate.onNavigationRequest`
203+
* `WebView.onPageStarted` -> `NavigationDelegate.onPageStarted`
204+
* `WebView.onPageFinished` -> `NavigationDelegate.onPageFinished`
205+
* `WebView.onProgress` -> `NavigationDelegate.onProgress`
206+
* `WebView.onWebResourceError` -> `NavigationDelegate.onWebResourceError`
207+
* The following fields from `WebView` have been moved to `WebViewController`:
208+
* `WebView.javascriptMode` -> `WebViewController.setJavaScriptMode`
209+
* `WebView.javascriptChannels` ->
210+
`WebViewController.addJavaScriptChannel`/`WebViewController.removeJavaScriptChannel`
211+
* `WebView.zoomEnabled` -> `WebViewController.enableZoom`
212+
* `WebView.userAgent` -> `WebViewController.setUserAgent`
213+
* `WebView.backgroundColor` -> `WebViewController.setBackgroundColor`
214+
* The following features have been moved to an Android implementation class. See section
215+
`Platform-Specific Features` for details on accessing Android platform specific features.
216+
* `WebView.debuggingEnabled` -> `static AndroidWebViewController.enableDebugging`
217+
* `WebView.initialMediaPlaybackPolicy` -> `AndroidWebViewController.setMediaPlaybackRequiresUserGesture`
218+
* The following features have been moved to an iOS implementation class. See section
219+
`Platform-Specific Features` for details on accessing iOS platform specific features.
220+
* `WebView.gestureNavigationEnabled` -> `WebKitWebViewController.setAllowsBackForwardNavigationGestures`
221+
* `WebView.initialMediaPlaybackPolicy` -> `WebKitWebViewControllerCreationParams.mediaTypesRequiringUserAction`
222+
* `WebView.allowsInlineMediaPlayback` -> `WebKitWebViewControllerCreationParams.allowsInlineMediaPlayback`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
targets:
2+
$default:
3+
sources:
4+
include:
5+
- lib/**
6+
# Some default includes that aren't really used here but will prevent
7+
# false-negative warnings:
8+
- $package$
9+
- lib/$lib$
10+
exclude:
11+
- '**/.*/**'
12+
- '**/build/**'
13+
builders:
14+
code_excerpter|code_excerpter:
15+
enabled: true

0 commit comments

Comments
 (0)