Flutter WebView
Webview is the fundamental widgets needed in mobile applications. Basically, webview is used to load the URL in view. Implementing webview in flutter is very easy if you have previous experience in native app development or not at all.
To use in the app in pubsec.yaml
need to add the dependencies and inside the terminal run command flutter packages get
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
webview_flutter: ^0.3.9+1
WebView is a widget and can be added in the widget tree. A simple example of Webview
class MyWebView extends StatefulWidget {
@override
_MyWebViewState createState() => _MyWebViewState();
}
class _MyWebViewState extends State<MyWebView> {
String url = "http://yubarajpoudel.com";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Profile"),
),
body: WebView(
initialUrl: url,
javascriptMode: JavascriptMode.unrestricted,
onPageFinished: (url) {
print("Loaded $url");
},
));
}
}

By default javascript in webview is disabled. JavascriptMode.unrestricted
properties enable the JavaScript in the webview.
Let's take another example of communicating between the Javascript and widget and we can easily change the state.
The simple Html page lets name it as a samplepage.html
` and keep in the assets/pages/
<html>
<head>
<title>Sample page</title>
<script>
function changeColor() {
var colors = ["black", "red", "green"];
var randonNumber = Math.floor(Math.random() * 3);
var myDiv = document.getElementById("container_box");
myDiv.style.backgroundColor = colors[randonNumber];
try { colorChanged.postMessage(colors[randonNumber]); } catch (err) {}
}
</script>
<style type="text/css">
#btn_color {
display: block;
margin: auto;
}
#container_box {
height: 500px;
width: 150px;
border: 1px solid #000 ;
margin: 0 auto;
}
</style>
</head>
<body>
<div id="container_box"></div> <br>
<button id="btn_color" onclick="changeColor()"> Change Color</button>
</body>
</html>

Above file is a simple HTML file in which the div
color is changed randomly when the button is clicked. Now I am showing the example how can we communicate between JavaScript and widget via JavaScriptChannel
. JavaScriptChannel
consists of Set of channelname
on which it listens triggered by the function with the same name in JavaScript
. In the below example colorChanged
is the channel name which is invoked in samplepage.html
changeColor
function.
class _MyWebView2State extends State<MyWebView2> {
WebViewController _controller;
String _inital = "Press button to change color";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("$_inital"),
),
body: WebView(
onWebViewCreated: (webViewController) {
_controller = webViewController;
_loadHtmlFromAssets();
},
javascriptMode: JavascriptMode.unrestricted,
javascriptChannels: Set.from([
JavascriptChannel(
name: "colorChanged",
onMessageReceived: (JavascriptMessage result) {
print("message ${result.message}");
setState(() {
_inital = "Color changed to ${result.message}";
});
}),
]),
));
}
_loadHtmlFromAssets() async {
String fileText =
await rootBundle.loadString('assets/pages/samplepage.html');
_controller.loadUrl(Uri.dataFromString(fileText,
mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
.toString());
}
}
When you run this you will get the following output.


Gesture detector in the webview
By default, the gesture in other widget in the widget tree has first priority than webview . However, the gesture detection priority can be changed in webview with respect to different events. Here let's take an example of implementing the webview with vertical gesture detector in the listview. By default, the listview has the first priority while scrolling up and down. But we can change to make the webview widget to scroll when scrolled in the webview by adding gesture set.
class MyWebView3 extends StatefulWidget {
@override
_MyWebView3State createState() => _MyWebView3State();
}
class _MyWebView3State extends State<MyWebView3> {
@override
Widget build(BuildContext context) {
List urls = [
"https://flutter.dev/",
"https://google.com/",
"https://github.com/yubarajpoudel"
];
List titles = ["flutter site", "google site", "author site"];
return Scaffold(
appBar: AppBar(
title: Text("Webview 3"),
),
body: ListView.builder(
itemCount: 3,
itemBuilder: (item, index) {
return Container(
height: 200.0,
child: ListTile(
title: Text(titles[index]),
subtitle: WebView(
initialUrl: urls[index],
gestureRecognizers: Set()
..add(Factory<VerticalDragGestureRecognizer>(
() => VerticalDragGestureRecognizer())),
)));
}),
);
}
}
..
operators here reduced the initialization and return the object. In the example, webview is scrolled when scrolled on top of webview widget. Running the Snippet produces the following output.

For more information check out the flutter developer session or watch the Emily Fortuna beautiful video about flutter_webview.
If you like to contribute to help the developer community we heartily welcome to join as the contributor. Please make a PR and we will review as soon as possible. For contribution and full code, please visit following GitHub link.