11import 'dart:async' ;
2- import 'dart:math' ;
32
4- import 'package:flutter/foundation.dart' ;
53import 'package:flutter/widgets.dart' ;
64import 'package:webview_flutter/webview_flutter.dart' as lib;
5+ import 'package:webview_flutter_android/webview_flutter_android.dart' as lib;
6+ import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart'
7+ as lib;
78
89import 'web_view.dart' ;
910
1011class WebViewState extends State <WebView > {
1112 final _timers = < Timer > [];
13+ late final lib.WebViewController _controller;
1214
1315 late double _aspectRatio;
1416 String ? _firstFinishedUrl;
1517 _Issue37 ? _issue37;
16- lib.WebViewController ? _wvc;
1718
1819 @override
1920 void initState () {
2021 super .initState ();
2122 _aspectRatio = widget.aspectRatio;
2223
24+ _initController ();
25+
2326 if (widget.unsupportedWorkaroundForIssue37) {
2427 _issue37 = _Issue37 (this );
25- _widgetsBindingInstance ? .addObserver (_issue37! );
28+ WidgetsBinding .instance .addObserver (_issue37! );
2629 }
2730 }
2831
29- @override
30- Widget build (BuildContext context) {
31- final webView = _buildWebView ();
32-
33- if (widget.unsupportedWorkaroundForIssue375 &&
34- defaultTargetPlatform == TargetPlatform .android) {
35- return LayoutBuilder (
36- builder: (context, constraints) {
37- final width = constraints.hasBoundedWidth
38- ? constraints.maxWidth
39- : MediaQuery .of (context).size.width;
40- final height = width / _aspectRatio;
41- return SizedBox (
42- height: min (
43- height,
44- constraints.hasBoundedHeight
45- ? constraints.maxHeight
46- : MediaQuery .of (context).size.height,
47- ),
48- width: width,
49- child: webView,
50- );
51- },
32+ void _initController () {
33+ var params = const lib.PlatformWebViewControllerCreationParams ();
34+ if (lib.WebViewPlatform .instance is lib.WebKitWebViewPlatform ) {
35+ params = lib.WebKitWebViewControllerCreationParams (
36+ allowsInlineMediaPlayback: true ,
37+ mediaTypesRequiringUserAction: widget.mediaPlaybackAlwaysAllow
38+ ? {}
39+ : {...lib.PlaybackMediaTypes .values},
40+ );
41+ }
42+
43+ _controller = lib.WebViewController .fromPlatformCreationParams (params)
44+ ..setJavaScriptMode (
45+ widget.js
46+ ? lib.JavaScriptMode .unrestricted
47+ : lib.JavaScriptMode .disabled,
48+ )
49+ ..setNavigationDelegate (
50+ lib.NavigationDelegate (
51+ onPageFinished: _onPageFinished,
52+ onNavigationRequest: widget.interceptNavigationRequest != null
53+ ? (req) => _interceptNavigationRequest (req)
54+ : null ,
55+ ),
56+ )
57+ ..setUserAgent (widget.userAgent)
58+ ..loadRequest (Uri .parse (widget.url));
59+
60+ final platformController = _controller.platform;
61+ if (platformController is lib.AndroidWebViewController ) {
62+ lib.AndroidWebViewController .enableDebugging (widget.debuggingEnabled);
63+ platformController.setMediaPlaybackRequiresUserGesture (
64+ ! widget.mediaPlaybackAlwaysAllow,
5265 );
5366 }
67+ }
5468
69+ @override
70+ Widget build (BuildContext context) {
5571 return AspectRatio (
5672 aspectRatio: _aspectRatio,
57- child: webView ,
73+ child: _buildWebView () ,
5874 );
5975 }
6076
@@ -63,7 +79,7 @@ class WebViewState extends State<WebView> {
6379 super .deactivate ();
6480
6581 if (widget.unsupportedWorkaroundForIssue37) {
66- _wvc ? .reload ();
82+ _controller .reload ();
6783 }
6884 }
6985
@@ -74,18 +90,21 @@ class WebViewState extends State<WebView> {
7490 }
7591
7692 if (_issue37 != null ) {
77- _widgetsBindingInstance ? .removeObserver (_issue37! );
93+ WidgetsBinding .instance .removeObserver (_issue37! );
7894 }
7995
8096 super .dispose ();
8197 }
8298
8399 Future <String > eval (String js) async {
84100 try {
85- return await _wvc! .runJavascriptReturningResult (js);
86- } catch (_) {
87- return '' ;
101+ final result = await _controller.runJavaScriptReturningResult (js);
102+ return '$result ' ;
103+ } catch (evalError) {
104+ debugPrint ('evalError: $evalError ' );
88105 }
106+
107+ return '' ;
89108 }
90109
91110 Future <void > _autoResize () async {
@@ -111,36 +130,22 @@ class WebViewState extends State<WebView> {
111130 }
112131 }
113132
114- Widget _buildWebView () => lib.WebView (
115- debuggingEnabled: widget.debuggingEnabled,
116- initialUrl: widget.url,
117- initialMediaPlaybackPolicy: widget.mediaPlaybackAlwaysAllow
118- ? lib.AutoMediaPlaybackPolicy .always_allow
119- : lib.AutoMediaPlaybackPolicy
120- .require_user_action_for_all_media_types,
121- javascriptMode: widget.js
122- ? lib.JavascriptMode .unrestricted
123- : lib.JavascriptMode .disabled,
133+ Widget _buildWebView () => lib.WebViewWidget (
134+ controller: _controller,
124135 key: Key (widget.url),
125- navigationDelegate: widget.interceptNavigationRequest != null
126- ? (req) => _interceptNavigationRequest (req)
127- : null ,
128- onPageFinished: _onPageFinished,
129- onWebViewCreated: (c) => _wvc = c,
130- userAgent: widget.userAgent,
131136 );
132137
133138 lib.NavigationDecision _interceptNavigationRequest (
134139 lib.NavigationRequest req,
135140 ) {
136141 var intercepted = false ;
137-
138- if (widget.interceptNavigationRequest != null &&
142+ final callback = widget.interceptNavigationRequest;
143+ if (callback != null &&
139144 _firstFinishedUrl != null &&
140- req.isForMainFrame &&
145+ req.isMainFrame &&
141146 req.url != widget.url &&
142147 req.url != _firstFinishedUrl) {
143- intercepted = widget. interceptNavigationRequest ! (req.url);
148+ intercepted = callback (req.url);
144149 }
145150
146151 return intercepted
@@ -165,9 +170,6 @@ class WebViewState extends State<WebView> {
165170 }
166171}
167172
168- // TODO: remove workaround when our minimum Flutter version >2.12
169- WidgetsBinding ? get _widgetsBindingInstance => WidgetsBinding .instance;
170-
171173class _Issue37 with WidgetsBindingObserver {
172174 final WebViewState wvs;
173175
@@ -176,7 +178,7 @@ class _Issue37 with WidgetsBindingObserver {
176178 @override
177179 void didChangeAppLifecycleState (AppLifecycleState state) {
178180 if (state == AppLifecycleState .paused) {
179- wvs._wvc ? .reload ();
181+ wvs._controller .reload ();
180182 }
181183 }
182184}
0 commit comments