This repository was archived by the owner on Feb 22, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
[webview_flutter] Copies app-facing implementation of webview_flutter from v4_webview #6856
Merged
auto-submit
merged 28 commits into
flutter:main
from
bparrishMines:webview_flutter_release
Dec 17, 2022
Merged
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
7f876d1
copy code from v4_webview
bparrishMines 56fceb9
version bump and readme update
bparrishMines 2a4b7d3
work towards better readme
bparrishMines e90e7df
Merge branch 'main' of github.com:flutter/plugins into webview_flutte…
bparrishMines b2480f8
improvements
bparrishMines 0d4e703
more readme progress
bparrishMines 9968f38
Merge branch 'main' of github.com:flutter/plugins into webview_flutte…
bparrishMines 301fafa
improvements
bparrishMines e56c091
fix main and update more readme
bparrishMines 65d28ed
excerpt changes and more 3.0 diffs
bparrishMines c41fa5b
cookie manager update
bparrishMines f5e7243
remove packages from exclude list
bparrishMines 720082e
lint
bparrishMines de00284
better range
bparrishMines fc2d6cb
isForMainFrame
bparrishMines f1c7a65
load page after waiting for widget
bparrishMines b206a23
fix integration tests
bparrishMines 998d8ae
Merge branch 'main' of github.com:flutter/plugins into webview_flutte…
bparrishMines a496fef
improve readme a bit
bparrishMines feb0b2e
collapse changelong. update platform-specific wording. include in exc…
bparrishMines fcf987d
use platform implementation packages
bparrishMines 4ff354b
include missing exports
bparrishMines 72f1db8
PR comments
bparrishMines 45d1a34
correct spelling
bparrishMines cc30a02
Merge branch 'main' of github.com:flutter/plugins into webview_flutte…
bparrishMines cc24cbb
interface dev dependency
bparrishMines 52069b3
move other usage above migration
bparrishMines dbc20fa
remove interface classes
bparrishMines File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,73 @@ | ||
# WebView for Flutter | ||
|
||
<?code-excerpt path-base="excerpts/packages/webview_flutter_example"?> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! You can remove this package from script/configs/temp_exclude_excerpt.yaml in this PR as well. |
||
|
||
[](https://pub.dev/packages/webview_flutter) | ||
|
||
A Flutter plugin that provides a WebView widget. | ||
|
||
On iOS the WebView widget is backed by a [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview); | ||
On iOS the WebView widget is backed by a [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview). | ||
On Android the WebView widget is backed by a [WebView](https://developer.android.com/reference/android/webkit/WebView). | ||
|
||
| | Android | iOS | | ||
|-------------|----------------|------| | ||
| **Support** | SDK 19+ or 20+ | 9.0+ | | ||
|
||
## Usage | ||
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. | ||
|
||
You can now include a WebView widget in your widget tree. See the | ||
[WebView](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebView-class.html) | ||
widget's Dartdoc for more details on how to use the widget. | ||
Add `webview_flutter` as a [dependency in your pubspec.yaml file](https://pub.dev/packages/webview_flutter/install). | ||
|
||
You can now display a WebView by: | ||
|
||
1. Instantiating a [WebViewController](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewController-class.html). | ||
|
||
<?code-excerpt "simple_example.dart (webview_controller)"?> | ||
```dart | ||
controller = WebViewController() | ||
..setJavaScriptMode(JavaScriptMode.unrestricted) | ||
..setBackgroundColor(const Color(0x00000000)) | ||
..setNavigationDelegate( | ||
NavigationDelegate( | ||
onProgress: (int progress) { | ||
// Update loading bar. | ||
}, | ||
onPageStarted: (String url) {}, | ||
onPageFinished: (String url) {}, | ||
onWebResourceError: (WebResourceError error) {}, | ||
onNavigationRequest: (NavigationRequest request) { | ||
if (request.url.startsWith('https://www.youtube.com/')) { | ||
return NavigationDecision.prevent; | ||
} | ||
return NavigationDecision.navigate; | ||
}, | ||
), | ||
) | ||
..loadRequest(Uri.parse('https://flutter.dev')); | ||
``` | ||
|
||
## Android Platform Views | ||
This plugin uses | ||
[Platform Views](https://flutter.dev/docs/development/platform-integration/platform-views) to embed | ||
the Android’s webview within the Flutter app. It supports two modes: | ||
*hybrid composition* (the current default) and *virtual display*. | ||
2. Passing the controller to a [WebViewWidget](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewWidget-class.html). | ||
|
||
Here are some points to consider when choosing between the two: | ||
<?code-excerpt "simple_example.dart (webview_widget)"?> | ||
```dart | ||
@override | ||
Widget build(BuildContext context) { | ||
return Scaffold( | ||
appBar: AppBar(title: const Text('Flutter Simple Example')), | ||
body: WebViewWidget(controller: controller), | ||
); | ||
} | ||
``` | ||
|
||
* *Hybrid composition* has built-in keyboard support while *virtual display* has multiple | ||
[keyboard issues](https://github.com/flutter/flutter/issues?q=is%3Aopen+label%3Avd-only+label%3A%22p%3A+webview-keyboard%22). | ||
* *Hybrid composition* requires Android SDK 19+ while *virtual display* requires Android SDK 20+. | ||
* *Hybrid composition* and *virtual display* have different | ||
[performance tradeoffs](https://flutter.dev/docs/development/platform-integration/platform-views#performance). | ||
See the Dartdocs for [WebViewController](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewController-class.html) | ||
and [WebViewWidget](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewWidget-class.html) | ||
for more details. | ||
|
||
### Android Platform Views | ||
|
||
### Using Hybrid Composition | ||
This plugin uses | ||
[Platform Views](https://flutter.dev/docs/development/platform-integration/platform-views) to embed | ||
the Android’s WebView within the Flutter app. | ||
|
||
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: | ||
You should however make sure to set the correct `minSdkVersion` in `android/app/build.gradle` if it was previously lower than 19: | ||
|
||
```groovy | ||
android { | ||
|
@@ -45,47 +77,67 @@ android { | |
} | ||
``` | ||
|
||
### Using Virtual displays | ||
### Platform-Specific Features | ||
|
||
1. Set the correct `minSdkVersion` in `android/app/build.gradle` (if it was previously lower than 20): | ||
Many classes have a subclass or an underlying implementation that provides access to platform-specific | ||
features. | ||
|
||
```groovy | ||
android { | ||
defaultConfig { | ||
minSdkVersion 20 | ||
} | ||
} | ||
``` | ||
To access platform-specific features, start by adding the platform implementation packages to your | ||
app or package: | ||
|
||
2. Set `WebView.platform = AndroidWebView();` in `initState()`. | ||
For example: | ||
* **Android**: [webview_flutter_android](https://pub.dev/packages/webview_flutter_android/install) | ||
* **iOS**: [webview_flutter_wkwebview](https://pub.dev/packages/webview_flutter_wkwebview/install) | ||
|
||
```dart | ||
import 'dart:io'; | ||
Next, add the imports of the implementation packages to your app or package: | ||
|
||
import 'package:webview_flutter/webview_flutter.dart'; | ||
<?code-excerpt "main.dart (platform_imports)"?> | ||
```dart | ||
// Import for Android features. | ||
import 'package:webview_flutter_android/webview_flutter_android.dart'; | ||
// Import for iOS features. | ||
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart'; | ||
``` | ||
|
||
class WebViewExample extends StatefulWidget { | ||
@override | ||
WebViewExampleState createState() => WebViewExampleState(); | ||
} | ||
Now, additional features can be accessed through the platform implementations. Classes | ||
`WebViewController`, `WebViewWidget`, `NavigationDelegate`, and `WebViewCookieManager` pass their | ||
functionality to a class provided by the current platform. Below are a couple of ways to access | ||
additional functionality provided by the platform and is followed by an example. | ||
|
||
1. Pass a creation params class provided by a platform implementation to a `fromPlatformCreationParams` | ||
constructor (e.g. `WebViewController.fromPlatformCreationParams`, | ||
`WebViewWidget.fromPlatformCreationParams`, etc.). | ||
2. Call methods on a platform implementation of a class by using the `platform` field (e.g. | ||
`WebViewController.platform`, `WebViewWidget.platform`, etc.). | ||
|
||
Below is an example of setting additional iOS and Android parameters on the `WebViewController`. | ||
|
||
<?code-excerpt "main.dart (platform_features)"?> | ||
```dart | ||
late final PlatformWebViewControllerCreationParams params; | ||
if (WebViewPlatform.instance is WebKitWebViewPlatform) { | ||
params = WebKitWebViewControllerCreationParams( | ||
allowsInlineMediaPlayback: true, | ||
mediaTypesRequiringUserAction: const <PlaybackMediaTypes>{}, | ||
); | ||
} else { | ||
params = const PlatformWebViewControllerCreationParams(); | ||
} | ||
|
||
class WebViewExampleState extends State<WebViewExample> { | ||
@override | ||
void initState() { | ||
super.initState(); | ||
// Enable virtual display. | ||
if (Platform.isAndroid) WebView.platform = AndroidWebView(); | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return WebView( | ||
initialUrl: 'https://flutter.dev', | ||
); | ||
} | ||
} | ||
``` | ||
final WebViewController controller = | ||
WebViewController.fromPlatformCreationParams(params); | ||
// ··· | ||
if (controller.platform is AndroidWebViewController) { | ||
AndroidWebViewController.enableDebugging(true); | ||
(controller.platform as AndroidWebViewController) | ||
.setMediaPlaybackRequiresUserGesture(false); | ||
} | ||
``` | ||
|
||
See https://pub.dev/documentation/webview_flutter_android/latest/webview_flutter_android/webview_flutter_android-library.html | ||
for more details on Android features. | ||
|
||
See https://pub.dev/documentation/webview_flutter_wkwebview/latest/webview_flutter_wkwebview/webview_flutter_wkwebview-library.html | ||
for more details on iOS features. | ||
bparrishMines marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Enable Material Components for Android | ||
|
||
|
@@ -95,4 +147,76 @@ follow the steps described in the [Enabling Material Components instructions](ht | |
### Setting custom headers on POST requests | ||
|
||
Currently, setting custom headers when making a post request with the WebViewController's `loadRequest` method is not supported on Android. | ||
If you require this functionality, a workaround is to make the request manually, and then load the response data using `loadHTMLString` instead. | ||
If you require this functionality, a workaround is to make the request manually, and then load the response data using `loadHtmlString` instead. | ||
|
||
## Migrating from 3.0 to 4.0 | ||
|
||
### Instantiating WebViewController | ||
|
||
In version 3.0 and below, `WebViewController` could only be retrieved in a callback after the | ||
`WebView` was added to the widget tree. Now, `WebViewController` must be instantiated and can be | ||
used before it is added to the widget tree. See `Usage` section above for an example. | ||
|
||
### Replacing WebView Functionality | ||
|
||
The `WebView` class has been removed and its functionality has been split into `WebViewController` | ||
and `WebViewWidget`. | ||
|
||
`WebViewController` handles all functionality that is associated with the underlying web view | ||
provided by each platform. (e.g., loading a url, setting the background color of the underlying | ||
platform view, or clearing the cache). | ||
|
||
`WebViewWidget` takes a `WebViewController` and handles all Flutter widget related functionality | ||
(e.g., layout direction, gesture recognizers). | ||
|
||
See the Dartdocs for [WebViewController](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewController-class.html) | ||
and [WebViewWidget](https://pub.dev/documentation/webview_flutter/latest/webview_flutter/WebViewWidget-class.html) | ||
for more details. | ||
|
||
### PlatformView Implementation on Android | ||
|
||
The PlatformView implementation for Android is currently no longer configurable. It uses Texture | ||
Layer Hybrid Composition on versions 23+ and automatically fallbacks to Hybrid Composition for | ||
version 19-23. See https://github.com/flutter/flutter/issues/108106 for progress on manually | ||
switching to Hybrid Composition on versions 23+. | ||
|
||
### API Changes | ||
|
||
Below is a non-exhaustive list of changes to the API: | ||
stuartmorgan-g marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
* `WebViewController.clearCache` no longer clears local storage. Please use | ||
`WebViewController.clearLocalStorage`. | ||
* `WebViewController.clearCache` no longer reloads the page. | ||
* `WebViewController.loadUrl` has been removed. Please use `WebViewController.loadRequest`. | ||
* `WebViewController.evaluateJavascript` has been removed. Please use | ||
`WebViewController.runJavaScript` or `WebViewController.runJavaScriptReturningResult`. | ||
* `WebViewController.getScrollX` and `WebViewController.getScrollY` have been removed and have | ||
been replaced by `WebViewController.getScrollPosition`. | ||
* `WebViewController.runJavaScriptReturningResult` now returns an `Object` and not a `String`. This | ||
will attempt to return a `bool` or `num` if the return value can be parsed. | ||
* `CookieManager` is replaced by `WebViewCookieManager`. | ||
* `NavigationDelegate.onWebResourceError` callback includes errors that are not from the main frame. | ||
Use the `WebResourceError.isForMainFrame` field to filter errors. | ||
* The following fields from `WebView` have been moved to `NavigationDelegate`. They can be added to | ||
a WebView with `WebViewController.setNavigationDelegate`. | ||
* `WebView.navigationDelegate` -> `NavigationDelegate.onNavigationRequest` | ||
* `WebView.onPageStarted` -> `NavigationDelegate.onPageStarted` | ||
* `WebView.onPageFinished` -> `NavigationDelegate.onPageFinished` | ||
* `WebView.onProgress` -> `NavigationDelegate.onProgress` | ||
* `WebView.onWebResourceError` -> `NavigationDelegate.onWebResourceError` | ||
* The following fields from `WebView` have been moved to `WebViewController`: | ||
* `WebView.javascriptMode` -> `WebViewController.setJavaScriptMode` | ||
* `WebView.javascriptChannels` -> | ||
`WebViewController.addJavaScriptChannel`/`WebViewController.removeJavaScriptChannel` | ||
* `WebView.zoomEnabled` -> `WebViewController.enableZoom` | ||
* `WebView.userAgent` -> `WebViewController.setUserAgent` | ||
* `WebView.backgroundColor` -> `WebViewController.setBackgroundColor` | ||
* The following features have been moved to an Android implementation class. See section | ||
`Platform-Specific Features` for details on accessing Android platform specific features. | ||
* `WebView.debuggingEnabled` -> `static AndroidWebViewController.enableDebugging` | ||
* `WebView.initialMediaPlaybackPolicy` -> `AndroidWebViewController.setMediaPlaybackRequiresUserGesture` | ||
* The following features have been moved to an iOS implementation class. See section | ||
`Platform-Specific Features` for details on accessing iOS platform specific features. | ||
* `WebView.gestureNavigationEnabled` -> `WebKitWebViewController.setAllowsBackForwardNavigationGestures` | ||
* `WebView.initialMediaPlaybackPolicy` -> `WebKitWebViewControllerCreationParams.mediaTypesRequiringUserAction` | ||
* `WebView.allowsInlineMediaPlayback` -> `WebKitWebViewControllerCreationParams.allowsInlineMediaPlayback` |
15 changes: 15 additions & 0 deletions
15
packages/webview_flutter/webview_flutter/example/build.excerpt.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
targets: | ||
$default: | ||
sources: | ||
include: | ||
- lib/** | ||
# Some default includes that aren't really used here but will prevent | ||
# false-negative warnings: | ||
- $package$ | ||
- lib/$lib$ | ||
exclude: | ||
- '**/.*/**' | ||
- '**/build/**' | ||
builders: | ||
code_excerpter|code_excerpter: | ||
enabled: true |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.