-
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
Changes from 19 commits
7f876d1
56fceb9
2a4b7d3
e90e7df
b2480f8
0d4e703
9968f38
301fafa
e56c091
65d28ed
c41fa5b
f5e7243
720082e
de00284
fc2d6cb
f1c7a65
b206a23
998d8ae
a496fef
feb0b2e
fcf987d
4ff354b
72f1db8
45d1a34
cc30a02
cc24cbb
52069b3
dbc20fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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"?> | ||
|
Contributor
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,54 +77,141 @@ 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 | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| 2. Set `WebView.platform = AndroidWebView();` in `initState()`. | ||
| For example: | ||
| To access platform specific features, start by including the import for the desired platform: | ||
|
||
|
|
||
| ```dart | ||
| import 'dart:io'; | ||
|
|
||
| import 'package:webview_flutter/webview_flutter.dart'; | ||
| <?code-excerpt "main.dart (platform_imports)"?> | ||
| ```dart | ||
| // Import for Android features. | ||
| import 'package:webview_flutter/android.dart'; | ||
| // ··· | ||
| // Import for iOS features. | ||
| import 'package: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 to 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); | ||
| } | ||
| ``` | ||
|
|
||
| ### Enable Material Components for Android | ||
| See https://pub.dev/documentation/webview_flutter/latest/android/android-library.html | ||
| for more details on Android features. | ||
|
|
||
| See https://pub.dev/documentation/webview_flutter/latest/wkwebview/wkwebview-library.html | ||
| for more details on iOS features. | ||
bparrishMines marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ## 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 it's functionality has been split into `WebViewController` | ||
|
||
| and `WebViewWidget`. | ||
|
|
||
| `WebViewController` handles all functionality that is associated with the underlying WebView | ||
|
||
| 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` | ||
|
|
||
| ## Enable Material Components for Android | ||
|
||
|
|
||
| To use Material Components when the user interacts with input elements in the WebView, | ||
| follow the steps described in the [Enabling Material Components instructions](https://flutter.dev/docs/deployment/android#enabling-material-components). | ||
|
|
||
| ### Setting custom headers on POST requests | ||
| ## 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. | ||
| 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's collapse these two and the underscores one above to a catch-all "Updates code for new analysis options." so there's less minor stuff listed in with the big change.