From 21f4838f415498f4f36f00e1672aa55036a0e0af Mon Sep 17 00:00:00 2001 From: Daniel Kao Date: Mon, 27 Jul 2020 17:52:37 +0800 Subject: [PATCH 1/4] use PlatformViewLink widget for Android WebView --- .../android/app/src/main/AndroidManifest.xml | 6 ++ lib/src/in_app_webview.dart | 61 +++++++++---------- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index b6bd289b..fefd2bec 100755 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -85,5 +85,11 @@ android:resource="@xml/provider_paths"/> + + + + diff --git a/lib/src/in_app_webview.dart b/lib/src/in_app_webview.dart index c031c3f3..19462ba9 100755 --- a/lib/src/in_app_webview.dart +++ b/lib/src/in_app_webview.dart @@ -3,6 +3,7 @@ import 'dart:typed_data'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter/gestures.dart'; @@ -339,41 +340,37 @@ class _InAppWebViewState extends State { @override Widget build(BuildContext context) { if (defaultTargetPlatform == TargetPlatform.android) { - return AndroidView( + return PlatformViewLink( viewType: 'com.pichillilorenzo/flutter_inappwebview', - onPlatformViewCreated: _onPlatformViewCreated, - gestureRecognizers: widget.gestureRecognizers, - layoutDirection: TextDirection.rtl, - creationParams: { - 'initialUrl': '${Uri.parse(widget.initialUrl)}', - 'initialFile': widget.initialFile, - 'initialData': widget.initialData?.toMap(), - 'initialHeaders': widget.initialHeaders, - 'initialOptions': widget.initialOptions?.toMap() ?? {}, - 'contextMenu': widget.contextMenu?.toMap() ?? {}, - 'windowId': widget.windowId + surfaceFactory: ( + BuildContext context, + PlatformViewController controller, + ) { + return AndroidViewSurface( + controller: controller, + gestureRecognizers: widget.gestureRecognizers ?? const >{}, + hitTestBehavior: PlatformViewHitTestBehavior.opaque, + ); + }, + onCreatePlatformView: (PlatformViewCreationParams params) { + return PlatformViewsService.initSurfaceAndroidView( + id: params.id, + viewType: 'com.pichillilorenzo/flutter_inappwebview', + layoutDirection: TextDirection.rtl, + creationParams: { + 'initialUrl': '${Uri.parse(widget.initialUrl)}', + 'initialFile': widget.initialFile, + 'initialData': widget.initialData?.toMap(), + 'initialHeaders': widget.initialHeaders, + 'initialOptions': widget.initialOptions?.toMap() ?? {} + }, + creationParamsCodec: const StandardMessageCodec(), + ) + ..addOnPlatformViewCreatedListener(params.onPlatformViewCreated) + ..addOnPlatformViewCreatedListener((id) => _onPlatformViewCreated(id)) + ..create(); }, - creationParamsCodec: const StandardMessageCodec(), ); - // onLongPress issue: https://github.com/flutter/plugins/blob/f31d16a6ca0c4bd6849cff925a00b6823973696b/packages/webview_flutter/lib/src/webview_android.dart#L31 - /*return GestureDetector( - onLongPress: () {}, - excludeFromSemantics: true, - child: AndroidView( - viewType: 'com.pichillilorenzo/flutter_inappwebview', - onPlatformViewCreated: _onPlatformViewCreated, - gestureRecognizers: widget.gestureRecognizers, - layoutDirection: TextDirection.rtl, - creationParams: { - 'initialUrl': '${Uri.parse(widget.initialUrl)}', - 'initialFile': widget.initialFile, - 'initialData': widget.initialData?.toMap(), - 'initialHeaders': widget.initialHeaders, - 'initialOptions': initialOptions - }, - creationParamsCodec: const StandardMessageCodec(), - ), - );*/ } else if (defaultTargetPlatform == TargetPlatform.iOS) { return UiKitView( viewType: 'com.pichillilorenzo/flutter_inappwebview', From 9f617d330cd49563afc0b82269f5f3fe56054fa3 Mon Sep 17 00:00:00 2001 From: tanay Date: Mon, 24 Aug 2020 11:48:50 -0400 Subject: [PATCH 2/4] Add AndroidInAppWebViewOption for using Hybrid Composition --- android/src/main/AndroidManifest.xml | 4 +- lib/src/in_app_webview.dart | 81 +++++++++++++++++----------- lib/src/webview_options.dart | 8 +++ 3 files changed, 61 insertions(+), 32 deletions(-) diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index d0d8adfc..a7309e1e 100755 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -5,6 +5,8 @@ + - \ No newline at end of file diff --git a/lib/src/in_app_webview.dart b/lib/src/in_app_webview.dart index 19462ba9..43696ec4 100755 --- a/lib/src/in_app_webview.dart +++ b/lib/src/in_app_webview.dart @@ -340,37 +340,56 @@ class _InAppWebViewState extends State { @override Widget build(BuildContext context) { if (defaultTargetPlatform == TargetPlatform.android) { - return PlatformViewLink( - viewType: 'com.pichillilorenzo/flutter_inappwebview', - surfaceFactory: ( - BuildContext context, - PlatformViewController controller, - ) { - return AndroidViewSurface( - controller: controller, - gestureRecognizers: widget.gestureRecognizers ?? const >{}, - hitTestBehavior: PlatformViewHitTestBehavior.opaque, - ); - }, - onCreatePlatformView: (PlatformViewCreationParams params) { - return PlatformViewsService.initSurfaceAndroidView( - id: params.id, - viewType: 'com.pichillilorenzo/flutter_inappwebview', - layoutDirection: TextDirection.rtl, - creationParams: { - 'initialUrl': '${Uri.parse(widget.initialUrl)}', - 'initialFile': widget.initialFile, - 'initialData': widget.initialData?.toMap(), - 'initialHeaders': widget.initialHeaders, - 'initialOptions': widget.initialOptions?.toMap() ?? {} - }, - creationParamsCodec: const StandardMessageCodec(), - ) - ..addOnPlatformViewCreatedListener(params.onPlatformViewCreated) - ..addOnPlatformViewCreatedListener((id) => _onPlatformViewCreated(id)) - ..create(); - }, - ); + if (widget.initialOptions.android.useHybridComposition) { + return PlatformViewLink( + viewType: 'com.pichillilorenzo/flutter_inappwebview', + surfaceFactory: ( + BuildContext context, + PlatformViewController controller, + ) { + return AndroidViewSurface( + controller: controller, + gestureRecognizers: widget.gestureRecognizers ?? const >{}, + hitTestBehavior: PlatformViewHitTestBehavior.opaque, + ); + }, + onCreatePlatformView: (PlatformViewCreationParams params) { + return PlatformViewsService.initSurfaceAndroidView( + id: params.id, + viewType: 'com.pichillilorenzo/flutter_inappwebview', + layoutDirection: TextDirection.rtl, + creationParams: { + 'initialUrl': '${Uri.parse(widget.initialUrl)}', + 'initialFile': widget.initialFile, + 'initialData': widget.initialData?.toMap(), + 'initialHeaders': widget.initialHeaders, + 'initialOptions': widget.initialOptions?.toMap() ?? {} + }, + creationParamsCodec: const StandardMessageCodec(), + ) + ..addOnPlatformViewCreatedListener(params.onPlatformViewCreated) + ..addOnPlatformViewCreatedListener((id) => _onPlatformViewCreated(id)) + ..create(); + }, + ); + } else { + return AndroidView( + viewType: 'com.pichillilorenzo/flutter_inappwebview', + onPlatformViewCreated: _onPlatformViewCreated, + gestureRecognizers: widget.gestureRecognizers, + layoutDirection: TextDirection.rtl, + creationParams: { + 'initialUrl': '${Uri.parse(widget.initialUrl)}', + 'initialFile': widget.initialFile, + 'initialData': widget.initialData?.toMap(), + 'initialHeaders': widget.initialHeaders, + 'initialOptions': widget.initialOptions?.toMap() ?? {}, + 'contextMenu': widget.contextMenu?.toMap() ?? {}, + 'windowId': widget.windowId + }, + creationParamsCodec: const StandardMessageCodec(), + ); + } } else if (defaultTargetPlatform == TargetPlatform.iOS) { return UiKitView( viewType: 'com.pichillilorenzo/flutter_inappwebview', diff --git a/lib/src/webview_options.dart b/lib/src/webview_options.dart index 506dd7c0..046f9908 100755 --- a/lib/src/webview_options.dart +++ b/lib/src/webview_options.dart @@ -470,6 +470,11 @@ class AndroidInAppWebViewOptions ///If the url request of a subframe matches the regular expression, then the request of that subframe is canceled. String regexToCancelSubFramesLoading; + ///Set to `true` to enable Flutter's new Hybrid Composition. The default value is `false`. + ///Hybrid Composition is supported starting with Flutter v1.20. + ///**NOTE**: It is recommended to use Hybrid Composition only on Android 10+ for a release app, as it can cause framerate drops on animations in Android 9 and lower. + bool useHybridComposition; + ///Set to `true` to be able to listen at the [WebView.androidShouldInterceptRequest] event. The default value is `false`. bool useShouldInterceptRequest; @@ -556,6 +561,7 @@ class AndroidInAppWebViewOptions this.initialScale = 0, this.supportMultipleWindows = false, this.regexToCancelSubFramesLoading, + this.useHybridComposition = false, this.useShouldInterceptRequest = false, this.useOnRenderProcessGone = false, this.overScrollMode = AndroidOverScrollMode.OVER_SCROLL_IF_CONTENT_SCROLLS, @@ -613,6 +619,7 @@ class AndroidInAppWebViewOptions "thirdPartyCookiesEnabled": thirdPartyCookiesEnabled, "hardwareAcceleration": hardwareAcceleration, "supportMultipleWindows": supportMultipleWindows, + "useHybridComposition": useHybridComposition, "regexToCancelSubFramesLoading": regexToCancelSubFramesLoading, "useShouldInterceptRequest": useShouldInterceptRequest, "useOnRenderProcessGone": useOnRenderProcessGone, @@ -676,6 +683,7 @@ class AndroidInAppWebViewOptions options.supportMultipleWindows = map["supportMultipleWindows"]; options.regexToCancelSubFramesLoading = map["regexToCancelSubFramesLoading"]; + options.useHybridComposition = map["useHybridComposition"]; options.useShouldInterceptRequest = map["useShouldInterceptRequest"]; options.useOnRenderProcessGone = map["useOnRenderProcessGone"]; options.overScrollMode = From ede4bd57cffd13188b82cd15c78987131a8c17df Mon Sep 17 00:00:00 2001 From: tanay Date: Mon, 24 Aug 2020 12:15:36 -0400 Subject: [PATCH 3/4] Update README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e6b0a8a3..451bce46 100755 --- a/README.md +++ b/README.md @@ -545,6 +545,7 @@ Instead, on the `onLoadStop` WebView event, you can use `callHandler` directly: ##### `InAppWebView` Android-specific options +* `useHybridComposition`: Set to `true` to use Flutter's new Hybrid Composition rendering method, which fixes all issues [here](https://github.com/flutter/flutter/issues/61133). The default value is `false`. Note that this option requires Flutter v1.20+ and should only be used on Android 10+ for release apps, as animations will drop frames on < Android 10. * `useShouldInterceptRequest`: Set to `true` to be able to listen at the `androidShouldInterceptRequest` event. The default value is `false`. * `useOnRenderProcessGone`: Set to `true` to be able to listen at the `androidOnRenderProcessGone` event. The default value is `false`. * `textZoom`: Sets the text zoom of the page in percent. The default value is `100`. From cb7715149a9aa5129ed00b99b39e5a2bf316fd3d Mon Sep 17 00:00:00 2001 From: Lorenzo Pichilli Date: Thu, 27 Aug 2020 15:42:13 +0200 Subject: [PATCH 4/4] Update in_app_webview.dart MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added missingĀ `contextMenu` and `windowId` creation params for Android Hybrid Composition --- lib/src/in_app_webview.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/src/in_app_webview.dart b/lib/src/in_app_webview.dart index 43696ec4..f211b3f6 100755 --- a/lib/src/in_app_webview.dart +++ b/lib/src/in_app_webview.dart @@ -363,7 +363,9 @@ class _InAppWebViewState extends State { 'initialFile': widget.initialFile, 'initialData': widget.initialData?.toMap(), 'initialHeaders': widget.initialHeaders, - 'initialOptions': widget.initialOptions?.toMap() ?? {} + 'initialOptions': widget.initialOptions?.toMap() ?? {}, + 'contextMenu': widget.contextMenu?.toMap() ?? {}, + 'windowId': widget.windowId }, creationParamsCodec: const StandardMessageCodec(), )