main.dart 8.4 KB

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