Tech With Sam

Tech With Sam

Flutter Advanced Webview Tutorial #1 - InAppWebview(Android & iOS).

Flutter Advanced Webview Tutorial #1 - InAppWebview(Android & iOS).

Subscribe to my newsletter and never miss my upcoming articles

Hello everyone and welcome to a brand new tutorial series on Flutter. Today we’re going to explore 3 advanced webview in an application using Flutter.

Image for post

In my previous article, I talked about How to convert your website into an application in a few minutes which is the very basis of creating a webview in flutter application, there I explained the usefulness of webview and many other kinds of stuff. In addition to the explanation, there is another aspect where the webview is very helpful, assuming your project as both website and mobile app, in the application you want to create/clown the about us on your website to the app in such cases you can use the help of webview by just displaying that every page of your website as webview on the app.

We’re going to have three different sessions for each webview, so everything won’t jam-packed. Each webview will look like the image below.

Image for post

Outline

  1. InAppWebview
  2. InAppBrowser
  3. ChromeSafariBrowser

We are going to make use of a package called flutter_inappwebview, this package has everything we’re going to be using, I recommend this package for your advances webview because it has a lot of features that are important so do check it out flutter_inappwebview.

PART ONE — InAppWebView.

I believe you already create your project, in your pubspec.yaml file add

dependencies:
   flutter_inappwebview: ^4.0.0+4

IMPORTANT Note for Android and iOS

If you’re running an application and need to access the binary messenger before runApp() has been called (for example, during plugin initialization), then you need to explicitly call the WidgetsFlutterBinding.ensureInitialized() first.

An example:

void main() {
 // it should be the first line in main method_
  WidgetsFlutterBinding.ensureInitialized();

  // rest of your app code_
  runApp(MyApp());
}

So your runApp() should basically look like this

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

If you run your app now with the package input you will get an error

the library might be using APIs not available in 16  
Suggestion: use a compatible library with a minSdk of at most 16,   
or increase this projects minSdk version to at least 17,   
or use tools:overrideLibrary="com.pichillilorenzo.flutter_inappwebview" to force usage (may lead to runtime failures)

This simply means that your minimum SDK is too low for the package, so to clear that navigate to <your-project>\android\app\build.gradle and update your minSdkVersion from 16 to maybe 18 or so, just leave it at 18. Then rerun the app everything should work fine now.

InAppWebView class

Flutter Widget for adding an inline native WebView integrated into the flutter widget tree.

The plugin relies on Flutter’s mechanism (in developers' preview) for embedding Android and iOS native views: AndroidView and UiKitView. Known issues are tagged with the platform-views label in the Flutter official repo. Keyboard support within webviews is also experimental.

To use the InAppWebView class on iOS you need to opt-in for the preview of the embedded view by adding a boolean property to the app's Info.plist file, with the key io.flutter.embedded_views_preview and the value YES.

Also, note that on Android it requires Android API 20+ (see AndroidView).

Use InAppWebViewController to control the WebView instance. Example:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State <MyApp> {

  InAppWebViewController webView;
  String url = "";
  double progress = 0;

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @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/",
                  initialHeaders: {},
                  initialOptions: InAppWebViewGroupOptions(
                    crossPlatform: InAppWebViewOptions(
                        debuggingEnabled: true,
                    )
                  ),
                  onWebViewCreated: (InAppWebViewController controller) {
                    webView = 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 (webView != null) {
                      webView.goBack();
                    }
                  },
                ),
                RaisedButton(
                  child: Icon(Icons.arrow_forward),
                  onPressed: () {
                    if (webView != null) {
                      webView.goForward();
                    }
                  },
                ),
                RaisedButton(
                  child: Icon(Icons.refresh),
                  onPressed: () {
                    if (webView != null) {
                      webView.reload();
                    }
                  },
                ),
              ],
            ),
        ])),
      ),
    );
  }
}

Screenshots: iOS & Android

Image for post Image for post

That’s it we’re done for the part1 of this advanced webview, do stay updated by following me to receive updates when other sessions is been posted.

Source code with more functionalities 👇 do well by staring ⭐ the repo

I hope you have learned something, kindly press the clap button as many time you want if you enjoy it, and feel free to ask a question. Thanks for reading

🔗 Social Media / Let's Connect 🔗 ==> Github | Twitter | Youtube | WhatsApp | LinkedIn | Patreon | Facebook.

Join the Flutter Dev Community 👨‍💻👨‍💻 ==> Facebook | Telegram | WhatsApp | Signal.

Subscribe to my Telegram channel | Youtube channel | and also to hashnode newsletter in the input box above 👆👆. Thanks

Happy Fluttering 🥰👨‍💻

#flutter#android#dart#hashnode#2articles1week
 
Share this
Proudly part of