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 eventsmethods, 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.

Main classes

This is a list of the main classes the plugin offers:

  • InAppWebView: Flutter widget for adding an inline native WebView integrated into the Flutter widget tree.
  • ContextMenu: class that represents the WebView context menu.
  • HeadlessInAppWebView: class that represents a WebView in headless mode. It can be used to run a WebView in background without attaching an InAppWebView to the widget tree.
  • InAppBrowser: in-app browser using native WebView.
  • ChromeSafariBrowser: in-app browser using Chrome Custom Tabs on Android or SFSafariViewController on iOS.
  • InAppLocalhostServer: class that allows you to create a simple server on http://localhost:[port]/. The default port value is 8080.
  • CookieManager: class that implements a singleton object (shared instance), which manages the cookies used by WebView instances.
  • HttpAuthCredentialDatabase: class that implements a singleton object (shared instance) that manages the shared HTTP auth credentials cache.
  • WebStorageManager: class that implements a singleton object (shared instance), which manages the web storage used by WebView instances.

In this article, I’m going to show in particular the InAppWebView widget, which is the most popular of them.

InAppWebView is a widget like any other!

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:

  • initialUrl: initial URL that will be loaded.
  • initialOptions: initial WebView options that will be used.
  • gestureRecognizers: specifies which gestures should be consumed by the WebView.
  • initialData: initial InAppWebViewInitialData that will be loaded, such as an HTML string.
  • initialFile: initial asset file that will be loaded (check the “Load a file inside assets folder” section).
  • initialHeaders: initial headers that will be used.
  • contextMenu: context menu that contains custom menu items.

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.

Use InAppWebViewController to control your WebView

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.

InAppWebView Events

The InAppWebView widget offers a variety of events! Here’s a few of them:

  • onLoadStart: event fired when the WebView starts to load an URL.
  • onLoadStop: event fired when the WebView finishes loading an URL.
  • onLoadHttpError: event fired when the WebView main page receives an HTTP error.
  • onConsoleMessage: event fired when the WebView receives a JavaScript console message (such as console.log , console.error etc.).
  • shouldOverrideUrlLoading: gives the host application a chance to take control when a URL is about to be loaded in the current WebView.
  • onDownloadStart: event fired when WebView recognizes a downloadable file.
  • onReceivedHttpAuthRequest: event fired when the WebView received an HTTP authentication request. The default behavior is to cancel the request.
  • onReceivedServerTrustAuthRequest: event fired when the WebView need to perform server trust authentication (certificate validation).
  • onPrint: event fired when window.print() is called from JavaScript side.
  • onCreateWindow: event fired when the InAppWebView requests the host application to create a new window, for example when trying to open a link with 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.

InAppWebView Simple Example

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

InAppWebView: the real power of WebViews in Flutter
101.30 GEEK