What is [flutter_inappwebview](https://github.com/pichillilorenzo/flutter_inappwebview)
? It’s a Flutter plugin that allows you to incorporate WebView widgets into your Flutter app, to use headless WebViews or to use in-app browsers.
So, what’s the difference between [webview_flutter](https://pub.dev/packages/webview_flutter)
(the official Flutter plugin) and [flutter_webview_plugin](https://pub.dev/packages/flutter_webview_plugin)
?
Compared to all other WebView plugins, it is feature-rich: a lot of events, methods, and options to control WebViews. Furthermore, they do not have good documentation on their API or, at least, it is not complete — while every feature of flutter_inappwebview
is almost completely documented (just check the API Reference on pub.dev).
In this article, I’m going to present the main classes and some examples of the InAppWebView
widget that people were asking about on the official flutter_inappwebview repository (issue section) and on StackOverflow.
This is a list of the main classes the plugin offers:
InAppWebView
to the widget tree.http://localhost:[port]/
. The default port
value is 8080.In this article, I’m going to show in particular the InAppWebView
widget, which is the most popular of them.
Adding the InAppWebView widget
into your app is very simple. It’s just a widget like any other Flutter widget: InAppWebView(initialUrl: 'https://github.com/flutter')
.
NOTE: To use it on iOS, you need to opt in for the embedded views preview by adding a boolean property to the app’s Info.plist
file, with the key io.flutter.embedded_views_preview
and the value YES
.
This widget has a set of initial attributes that you can use to initialize the WebView:
InAppWebViewInitialData
that will be loaded, such as an HTML string.The list of all available WebView options is quite long. For example, you can enable/disable JavaScript using the javascriptEnabled
option or enable/disable cache using the cacheEnabled
option. The full list of all options is available here.
To control the WebView, you have the InAppWebViewController
class. This controller is returned by the onWebViewCreated
callback when the WebView is ready to be used.
Through it, you can control your WebView or access its properties, such as the current URL (using the getUrl
method). Some other possible methods are loadUrl
to load a new URL, postUrl
to load a given URL with custom data using POST method, evaluateJavascript
to evaluate JavaScript code into the WebView and to get the result of the evaluation, takeScreenshot
to take the screenshot (in PNG format) of the WebView’s visible viewport, getCertificate
to get either the SSL certificate for the main top-level page or null
if there is no certificate. The full list of all methods you can use is quite long and available here.
The InAppWebView
widget offers a variety of events! Here’s a few of them:
console.log
, console.error
etc.).window.print(
) is called from JavaScript side.target="_blank"
or when window.open()
is called by JavaScript side.There are many, many more! I recommend checking the API Reference to get more details. As for the WebView options and methods, the full list of all WebView events is quite long and available here.
Here is a simple example that shows an InAppWebView
widget, its current URL, and 3 buttons: one to go back, one to go forward, and another one to reload the current page.
This is the full code example:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
InAppWebViewController _webViewController;
String url = "";
double progress = 0;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('InAppWebView Example'),
),
body: Container(
child: Column(children: <Widget>[
Container(
padding: EdgeInsets.all(20.0),
child: Text(
"CURRENT URL\n${(url.length > 50) ? url.substring(0, 50) + "..." : url}"),
),
Container(
padding: EdgeInsets.all(10.0),
child: progress < 1.0
? LinearProgressIndicator(value: progress)
: Container()),
Expanded(
child: Container(
margin: const EdgeInsets.all(10.0),
decoration:
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
child: InAppWebView(
initialUrl: "https://flutter.dev/",
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
debuggingEnabled: true,
)
),
onWebViewCreated: (InAppWebViewController controller) {
_webViewController = controller;
},
onLoadStart: (InAppWebViewController controller, String url) {
setState(() {
this.url = url;
});
},
onLoadStop: (InAppWebViewController controller, String url) async {
setState(() {
this.url = url;
});
},
onProgressChanged: (InAppWebViewController controller, int progress) {
setState(() {
this.progress = progress / 100;
});
},
),
),
),
ButtonBar(
alignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Icon(Icons.arrow_back),
onPressed: () {
if (_webViewController != null) {
_webViewController.goBack();
}
},
),
RaisedButton(
child: Icon(Icons.arrow_forward),
onPressed: () {
if (_webViewController != null) {
_webViewController.goForward();
}
},
),
RaisedButton(
child: Icon(Icons.refresh),
onPressed: () {
if (_webViewController != null) {
_webViewController.reload();
}
},
),
],
),
])),
),
);
}
}
#flutter