import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_webview_plugin/flutter_webview_plugin.dart'; const kAndroidUserAgent = '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'; String selectedUrl = 'https://flutter.io'; // ignore: prefer_collection_literals final Set jsChannels = [ JavascriptChannel( name: 'Print', onMessageReceived: (JavascriptMessage message) { print(message.message); }), ].toSet(); void main() { WidgetsFlutterBinding.ensureInitialized(); runApp(MyApp()); } class MyApp extends StatelessWidget { final flutterWebViewPlugin = FlutterWebviewPlugin(); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter WebView Demo', theme: ThemeData( primarySwatch: Colors.blue, ), routes: { '/': (_) => const MyHomePage(title: 'Flutter WebView Demo'), '/widget': (_) { return WebviewScaffold( url: selectedUrl, javascriptChannels: jsChannels, mediaPlaybackRequiresUserGesture: false, appBar: AppBar( title: const Text('Widget WebView'), ), withZoom: true, withLocalStorage: true, hidden: true, initialChild: Container( color: Colors.redAccent, child: const Center( child: Text('Waiting.....'), ), ), bottomNavigationBar: BottomAppBar( child: Row( children: [ IconButton( icon: const Icon(Icons.arrow_back_ios), onPressed: () { flutterWebViewPlugin.goBack(); }, ), IconButton( icon: const Icon(Icons.arrow_forward_ios), onPressed: () { flutterWebViewPlugin.goForward(); }, ), IconButton( icon: const Icon(Icons.autorenew), onPressed: () { flutterWebViewPlugin.reload(); }, ), ], ), ), ); }, }, ); } } class MyHomePage extends StatefulWidget { const MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State { // Instance of WebView plugin final flutterWebViewPlugin = FlutterWebviewPlugin(); // On destroy stream StreamSubscription _onDestroy; // On urlChanged stream StreamSubscription _onUrlChanged; // On urlChanged stream StreamSubscription _onStateChanged; StreamSubscription _onHttpError; StreamSubscription _onProgressChanged; StreamSubscription _onScrollYChanged; StreamSubscription _onScrollXChanged; final _urlCtrl = TextEditingController(text: selectedUrl); final _codeCtrl = TextEditingController(text: 'window.navigator.userAgent'); final _scaffoldKey = GlobalKey(); final _history = []; @override void initState() { super.initState(); flutterWebViewPlugin.close(); _urlCtrl.addListener(() { selectedUrl = _urlCtrl.text; }); // Add a listener to on destroy WebView, so you can make came actions. _onDestroy = flutterWebViewPlugin.onDestroy.listen((_) { if (mounted) { // Actions like show a info toast. _scaffoldKey.currentState.showSnackBar( const SnackBar(content: const Text('Webview Destroyed'))); } }); // Add a listener to on url changed _onUrlChanged = flutterWebViewPlugin.onUrlChanged.listen((String url) { if (mounted) { setState(() { _history.add('onUrlChanged: $url'); }); } }); _onProgressChanged = flutterWebViewPlugin.onProgressChanged.listen((double progress) { if (mounted) { setState(() { _history.add('onProgressChanged: $progress'); }); } }); _onScrollYChanged = flutterWebViewPlugin.onScrollYChanged.listen((double y) { if (mounted) { setState(() { _history.add('Scroll in Y Direction: $y'); }); } }); _onScrollXChanged = flutterWebViewPlugin.onScrollXChanged.listen((double x) { if (mounted) { setState(() { _history.add('Scroll in X Direction: $x'); }); } }); _onStateChanged = flutterWebViewPlugin.onStateChanged.listen((WebViewStateChanged state) { if (mounted) { setState(() { _history.add('onStateChanged: ${state.type} ${state.url}'); }); } }); _onHttpError = flutterWebViewPlugin.onHttpError.listen((WebViewHttpError error) { if (mounted) { setState(() { _history.add('onHttpError: ${error.code} ${error.url}'); }); } }); } @override void dispose() { // Every listener should be canceled, the same should be done with this stream. _onDestroy.cancel(); _onUrlChanged.cancel(); _onStateChanged.cancel(); _onHttpError.cancel(); _onProgressChanged.cancel(); _onScrollXChanged.cancel(); _onScrollYChanged.cancel(); flutterWebViewPlugin.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( key: _scaffoldKey, appBar: AppBar( title: const Text('Plugin example app'), ), body: SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( padding: const EdgeInsets.all(24.0), child: TextField(controller: _urlCtrl), ), RaisedButton( onPressed: () { flutterWebViewPlugin.launch( selectedUrl, rect: Rect.fromLTWH( 0.0, 0.0, MediaQuery.of(context).size.width, 300.0), userAgent: kAndroidUserAgent, invalidUrlRegex: r'^(https).+(twitter)', // prevent redirecting to twitter when user click on its icon in flutter website ); }, child: const Text('Open Webview (rect)'), ), RaisedButton( onPressed: () { flutterWebViewPlugin.launch(selectedUrl, hidden: true); }, child: const Text('Open "hidden" Webview'), ), RaisedButton( onPressed: () { flutterWebViewPlugin.launch(selectedUrl); }, child: const Text('Open Fullscreen Webview'), ), RaisedButton( onPressed: () { Navigator.of(context).pushNamed('/widget'); }, child: const Text('Open widget webview'), ), Container( padding: const EdgeInsets.all(24.0), child: TextField(controller: _codeCtrl), ), RaisedButton( onPressed: () { final future = flutterWebViewPlugin.evalJavascript(_codeCtrl.text); future.then((String result) { setState(() { _history.add('eval: $result'); }); }); }, child: const Text('Eval some javascript'), ), RaisedButton( onPressed: () { setState(() { _history.clear(); }); flutterWebViewPlugin.close(); }, child: const Text('Close'), ), RaisedButton( onPressed: () { flutterWebViewPlugin.getCookies().then((m) { setState(() { _history.add('cookies: $m'); }); }); }, child: const Text('Cookies'), ), Text(_history.join('\n')) ], ), ), ); } }