Webview is typically a cross-platform library used to render web based User Interfaces in mobile or desktop applications
flutter_webview_plugin
package provides FlutterWebviewPlugin
and WebviewScaffold
to render a webview and interact with it
Check Flutter installation to setup Flutter
Use flutter create
command to create a Flutter project (here webview_app :
flutter create webview_app
Add flutter_webview_plugin
package to pubspec.yaml
dependencies:
flutter_webview_plugin: "0.3.11"
flutter:
sdk: flutter
Run following command to add dependency
flutter pub get
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
Create WebviewScaffold
widget which is like a Scaffold and contains properties for webview
A selectedUrl
String indicates the url being browsed
initialChild
can be used to show a widget while a page is loaded, whereas setting hidden
to true shows a circular progress indicator
@override
Widget build(BuildContext context) {
return WebviewScaffold(
url: selectedUrl,
mediaPlaybackRequiresUserGesture: false,
appBar: AppBar(
automaticallyImplyLeading: false,
title:Text("Webview Example App"),
bottom: AppBar(
automaticallyImplyLeading: false,
),
withZoom: true,
withLocalStorage: true,
hidden: false,
initialChild: Container(
color: Colors.redAccent,
child: const Center(
child: Text('Waiting.....'),
),
),
);
}
FlutterWebviewPlugin
instance Declare an instance of FlutterWebviewPlugin
which is a singleton instance linked to an unique webview
final flutterWebViewPlugin = FlutterWebviewPlugin();
Use it to initiate functions like reload, goForward, goBack() and to implement listeners like onUrlChanged, onHttpError etc
flutterWebViewPlugin.reload();
flutterWebViewPlugin.goForward();
flutterWebViewPlugin.goBack();
flutterWebViewPlugin.getCookies();
flutterWebViewPlugin.onUrlChanged.listen((String url) {
if (mounted) {
setState(() {
_urlCtrl.text = selectedUrl;
selectedUrl = url;
_history.add('onUrlChanged: $url');
});
}
});
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
// ignore: prefer_collection_literals
final Set<JavascriptChannel> jsChannels = [
JavascriptChannel(
name: 'Print',
onMessageReceived: (JavascriptMessage message) {
print(message.message);
}),
].toSet();
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(WebviewApp());
}
class WebviewApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter WebView Example App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routes: {
'/': (_) => const WebviewScreen(title: 'Flutter WebView Example App'),
},
);
}
}
class WebviewScreen extends StatefulWidget {
const WebviewScreen({Key key, this.title}) : super(key: key);
final String title;
@override
_WebviewScreenState createState() => _WebviewScreenState();
}
class _WebviewScreenState extends State<WebviewScreen> {
final flutterWebViewPlugin = FlutterWebviewPlugin();
String selectedUrl = 'https://flutter.io';
// On destroy stream
StreamSubscription _onDestroy;
// On urlChanged stream
StreamSubscription<String> _onUrlChanged;
StreamSubscription<WebViewStateChanged> _onStateChanged;
StreamSubscription<WebViewHttpError> _onHttpError;
StreamSubscription<double> _onProgressChanged;
StreamSubscription<double> _onScrollYChanged;
StreamSubscription<double> _onScrollXChanged;
final _urlCtrl = TextEditingController(text: 'https://flutter.io');
final _scaffoldKey = GlobalKey<ScaffoldState>();
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(() {
_urlCtrl.text = selectedUrl;
selectedUrl = url;
_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() {
_onDestroy.cancel();
_onUrlChanged.cancel();
_onStateChanged.cancel();
_onHttpError.cancel();
_onProgressChanged.cancel();
_onScrollXChanged.cancel();
_onScrollYChanged.cancel();
flutterWebViewPlugin.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return WebviewScaffold(
url: selectedUrl,
javascriptChannels: jsChannels,
mediaPlaybackRequiresUserGesture: false,
appBar: AppBar(
automaticallyImplyLeading: false,
title:Text("Webview Example App"),
bottom: AppBar(
automaticallyImplyLeading: false,
title: Row(
children: <Widget>[
Expanded(
flex: 1,
child: IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: () {
flutterWebViewPlugin.goBack();
},
),
),
Expanded(
flex: 1,
child: IconButton(
icon: const Icon(Icons.arrow_forward_ios),
onPressed: () {
flutterWebViewPlugin.goForward();
},
),
),
Expanded(
flex: 8,
child:Container(
padding: EdgeInsets.only(top:5, bottom:5),
color: Colors.white,
child: TextField(controller: _urlCtrl),
),
),
Expanded(
flex: 1,
child: IconButton(
icon: const Icon(Icons.autorenew),
onPressed: () {
flutterWebViewPlugin.reload();
},
),
),
],
),
),
),
withZoom: true,
withLocalStorage: true,
hidden: false,
initialChild: Container(
color: Colors.redAccent,
child: const Center(
child: Text('Waiting.....'),
),
),
bottomNavigationBar: Container(
height:100,
child:SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: Text('${selectedUrl}', style: TextStyle(color: Colors.black, fontWeight:FontWeight.normal, fontSize:15,)),
),
RaisedButton(
onPressed: () {
flutterWebViewPlugin.getCookies().then((m) {
setState(() {
_history.add('cookies: $m');
});
});
},
child: const Text('Cookies'),
),
Text(_history.join('\n'))
],
),
),
),
);
}
}
Ensure a supported device is connected or emulator/simulator is started
Go to project directory
Use flutter run
command to run
flutter run
It builds and runs app on an available android/ios device