main.dart 7.6 KB

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