main.dart 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
  4. const kAndroidUserAgent =
  5. 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Mobile Safari/537.36';
  6. String selectedUrl = 'https://flutter.io';
  7. // ignore: prefer_collection_literals
  8. final Set<JavascriptChannel> jsChannels = [
  9. JavascriptChannel(
  10. name: 'Print',
  11. onMessageReceived: (JavascriptMessage message) {
  12. print(message.message);
  13. }),
  14. ].toSet();
  15. void main() => runApp(MyApp());
  16. class MyApp extends StatelessWidget {
  17. final flutterWebViewPlugin = FlutterWebviewPlugin();
  18. @override
  19. Widget build(BuildContext context) {
  20. return MaterialApp(
  21. title: 'Flutter WebView Demo',
  22. theme: ThemeData(
  23. primarySwatch: Colors.blue,
  24. ),
  25. routes: {
  26. '/': (_) => const MyHomePage(title: 'Flutter WebView Demo'),
  27. '/widget': (_) {
  28. return WebviewScaffold(
  29. url: selectedUrl,
  30. javascriptChannels: jsChannels,
  31. appBar: AppBar(
  32. title: const Text('Widget WebView'),
  33. ),
  34. withZoom: true,
  35. withLocalStorage: true,
  36. hidden: true,
  37. initialChild: Container(
  38. color: Colors.redAccent,
  39. child: const Center(
  40. child: Text('Waiting.....'),
  41. ),
  42. ),
  43. bottomNavigationBar: BottomAppBar(
  44. child: Row(
  45. children: <Widget>[
  46. IconButton(
  47. icon: const Icon(Icons.arrow_back_ios),
  48. onPressed: () {
  49. flutterWebViewPlugin.goBack();
  50. },
  51. ),
  52. IconButton(
  53. icon: const Icon(Icons.arrow_forward_ios),
  54. onPressed: () {
  55. flutterWebViewPlugin.goForward();
  56. },
  57. ),
  58. IconButton(
  59. icon: const Icon(Icons.autorenew),
  60. onPressed: () {
  61. flutterWebViewPlugin.reload();
  62. },
  63. ),
  64. ],
  65. ),
  66. ),
  67. );
  68. },
  69. },
  70. );
  71. }
  72. }
  73. class MyHomePage extends StatefulWidget {
  74. const MyHomePage({Key key, this.title}) : super(key: key);
  75. final String title;
  76. @override
  77. _MyHomePageState createState() => _MyHomePageState();
  78. }
  79. class _MyHomePageState extends State<MyHomePage> {
  80. // Instance of WebView plugin
  81. final flutterWebViewPlugin = FlutterWebviewPlugin();
  82. // On destroy stream
  83. StreamSubscription _onDestroy;
  84. // On urlChanged stream
  85. StreamSubscription<String> _onUrlChanged;
  86. // On urlChanged stream
  87. StreamSubscription<WebViewStateChanged> _onStateChanged;
  88. StreamSubscription<WebViewHttpError> _onHttpError;
  89. StreamSubscription<double> _onProgressChanged;
  90. StreamSubscription<double> _onScrollYChanged;
  91. StreamSubscription<double> _onScrollXChanged;
  92. final _urlCtrl = TextEditingController(text: selectedUrl);
  93. final _codeCtrl = TextEditingController(text: 'window.navigator.userAgent');
  94. final _scaffoldKey = GlobalKey<ScaffoldState>();
  95. final _history = [];
  96. @override
  97. void initState() {
  98. super.initState();
  99. flutterWebViewPlugin.close();
  100. _urlCtrl.addListener(() {
  101. selectedUrl = _urlCtrl.text;
  102. });
  103. // Add a listener to on destroy WebView, so you can make came actions.
  104. _onDestroy = flutterWebViewPlugin.onDestroy.listen((_) {
  105. if (mounted) {
  106. // Actions like show a info toast.
  107. _scaffoldKey.currentState.showSnackBar(
  108. const SnackBar(content: const Text('Webview Destroyed')));
  109. }
  110. });
  111. // Add a listener to on url changed
  112. _onUrlChanged = flutterWebViewPlugin.onUrlChanged.listen((String url) {
  113. if (mounted) {
  114. setState(() {
  115. _history.add('onUrlChanged: $url');
  116. });
  117. }
  118. });
  119. _onProgressChanged =
  120. flutterWebViewPlugin.onProgressChanged.listen((double progress) {
  121. if (mounted) {
  122. setState(() {
  123. _history.add('onProgressChanged: $progress');
  124. });
  125. }
  126. });
  127. _onScrollYChanged =
  128. flutterWebViewPlugin.onScrollYChanged.listen((double y) {
  129. if (mounted) {
  130. setState(() {
  131. _history.add('Scroll in Y Direction: $y');
  132. });
  133. }
  134. });
  135. _onScrollXChanged =
  136. flutterWebViewPlugin.onScrollXChanged.listen((double x) {
  137. if (mounted) {
  138. setState(() {
  139. _history.add('Scroll in X Direction: $x');
  140. });
  141. }
  142. });
  143. _onStateChanged =
  144. flutterWebViewPlugin.onStateChanged.listen((WebViewStateChanged state) {
  145. if (mounted) {
  146. setState(() {
  147. _history.add('onStateChanged: ${state.type} ${state.url}');
  148. });
  149. }
  150. });
  151. _onHttpError =
  152. flutterWebViewPlugin.onHttpError.listen((WebViewHttpError error) {
  153. if (mounted) {
  154. setState(() {
  155. _history.add('onHttpError: ${error.code} ${error.url}');
  156. });
  157. }
  158. });
  159. }
  160. @override
  161. void dispose() {
  162. // Every listener should be canceled, the same should be done with this stream.
  163. _onDestroy.cancel();
  164. _onUrlChanged.cancel();
  165. _onStateChanged.cancel();
  166. _onHttpError.cancel();
  167. _onProgressChanged.cancel();
  168. _onScrollXChanged.cancel();
  169. _onScrollYChanged.cancel();
  170. flutterWebViewPlugin.dispose();
  171. super.dispose();
  172. }
  173. @override
  174. Widget build(BuildContext context) {
  175. return Scaffold(
  176. key: _scaffoldKey,
  177. appBar: AppBar(
  178. title: const Text('Plugin example app'),
  179. ),
  180. body: SingleChildScrollView(
  181. child: Column(
  182. mainAxisAlignment: MainAxisAlignment.center,
  183. children: [
  184. Container(
  185. padding: const EdgeInsets.all(24.0),
  186. child: TextField(controller: _urlCtrl),
  187. ),
  188. RaisedButton(
  189. onPressed: () {
  190. flutterWebViewPlugin.launch(
  191. selectedUrl,
  192. rect: Rect.fromLTWH(
  193. 0.0, 0.0, MediaQuery.of(context).size.width, 300.0),
  194. userAgent: kAndroidUserAgent,
  195. invalidUrlRegex:
  196. r'^(https).+(twitter)', // prevent redirecting to twitter when user click on its icon in flutter website
  197. );
  198. },
  199. child: const Text('Open Webview (rect)'),
  200. ),
  201. RaisedButton(
  202. onPressed: () {
  203. flutterWebViewPlugin.launch(selectedUrl, hidden: true);
  204. },
  205. child: const Text('Open "hidden" Webview'),
  206. ),
  207. RaisedButton(
  208. onPressed: () {
  209. flutterWebViewPlugin.launch(selectedUrl);
  210. },
  211. child: const Text('Open Fullscreen Webview'),
  212. ),
  213. RaisedButton(
  214. onPressed: () {
  215. Navigator.of(context).pushNamed('/widget');
  216. },
  217. child: const Text('Open widget webview'),
  218. ),
  219. Container(
  220. padding: const EdgeInsets.all(24.0),
  221. child: TextField(controller: _codeCtrl),
  222. ),
  223. RaisedButton(
  224. onPressed: () {
  225. final future =
  226. flutterWebViewPlugin.evalJavascript(_codeCtrl.text);
  227. future.then((String result) {
  228. setState(() {
  229. _history.add('eval: $result');
  230. });
  231. });
  232. },
  233. child: const Text('Eval some javascript'),
  234. ),
  235. RaisedButton(
  236. onPressed: () {
  237. setState(() {
  238. _history.clear();
  239. });
  240. flutterWebViewPlugin.close();
  241. },
  242. child: const Text('Close'),
  243. ),
  244. RaisedButton(
  245. onPressed: () {
  246. flutterWebViewPlugin.getCookies().then((m) {
  247. setState(() {
  248. _history.add('cookies: $m');
  249. });
  250. });
  251. },
  252. child: const Text('Cookies'),
  253. ),
  254. Text(_history.join('\n'))
  255. ],
  256. ),
  257. ),
  258. );
  259. }
  260. }