Flutter WebView

Flutter WebView:

In this tutorial, we are going to learn to create a WebView In Flutter App for both Android and IOS.

What is a WebView?

A “webview” is a browser having a URL bundled inside the mobile application and is called a hybrid app. By using this webview we are going to build mobile apps for Web technologies. but still, package it as a native app and we are putting these webview or hybrid apps into the app store. WebView makes turns your application to a web application. the beauty of webview is we no need to write browser URL in the mobile browser that displays web pages inside your application.

How WebView works in Flutter?

On iOS the WebView widget is backed by a WKWebView; On Android the WebView widget is backed by a WebView.

To use this WebView 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 will be YES.

How the WebView Widget Works?

On iOS, the WebView widget is backed by a WKWebView, the newer and now official UIKit control for displaying web views. On Android, the WebView widget is backed by a WebView.

What is WKWEBVIEW?

An object that displays interactive web content, such as for an in-app browser

Important:

Starting in iOS 8.0 and OS X 10.10, use WKWebView to add web content to your app. Do not use UIWebView or WebView.

You can use the WKWebView class to embed web content in your app. To create a WKWebView object, set it as the view, and send it a request to load web content. You can make POST requests with httpBody content in a WKWebView.

IN the backend how it works :

After creating a new WKWebView object using the init(frame:configuration:) method, you need to load the web content. Use the loadHTMLString(_:baseURL:) method to begin loading local HTML files or the load(_:) method to begin loading web content. Use the stopLoading() method to stop loading, and the isLoading property to find out if a web view is in the process of loading. Set the delegate property to an object conforming to the WKUIDelegate protocol to track the loading of web content.

To allow the user to move back and forward through the webpage history, use the goBack()and goForward() methods as actions for buttons. Use the canGoBack and canGoForwardproperties to disable the buttons when the user can’t move in a direction. By default, a web view automatically converts telephone numbers that appear in web content to Phone links. When a Phone link is tapped, the Phone app launches and dials the number. To turn off this default behavior, set the dataDetectorTypes property with a WKDataDetectorTypes bitfield that does not contain the phoneNumber flag.

For Android:

A View that displays web pages within your app without browser URL. a WebView is a good option for displaying trusted first-party content. A WebView is useful when you need increased control over the UI and advanced configuration options that will allow you to embed web pages in a specially-designed environment for your app

 

Although WebView objects provide increased control over the UI, there are alternatives that may provide similar functionality with various advantages: they require less configuration, may load and perform faster, provide improved privacy protections, and can access the browser’s cookies.

Consider using these alternatives to WebView if your app falls into the following use cases:

  • If you want to send users to a mobile site, build a progressive web app (PWA).
  • If you want to display third-party web content, send an intent to installed web browsers.
  • If you want to avoid leaving your app to open the browser, or if you want to customize the browser’s UI, useChrome Custom Tabs.

To start developing web pages for Android-powered devices using WebView objects, see the following documents.

 

Creating home Screen in fluter webview:

use the below line of code to create home screen in flutter webview as shown below.

void main() => runApp(MaterialApp(home: WebViewExample()));

 

Fetching the web page into your APP:

using the below code we are fetching web page into your app by using initial URL  this initial URL method fetches this webpage into your and looks like an app and it is called a webview.

 

return WebView(

          initialUrl: ‘https://www.iflutter.in’,

          javascriptMode: JavascriptMode.unrestricted,

          onWebViewCreated: (WebViewController webViewController) {

            _controller.complete(webViewController);

          },

Creating the WebView In Flutter App:

Follow the below methods to create a WebView in Flutter.

 

Add the dependency package:

adding the dependency package to pubspec.yaml file. use the below code to add dependency package. After adding the dependency package run the get package method to import all the required files to the app.

dependencies:
webview_flutter: ^0.3.6

Install the package:

You can install the package from the command line using the below code with Flutter as shown.

$ flutter packages get

Importing the Package:

After, Adding the dependency package to the pubspec.yaml file, you can now import the package into the dart code by using the below code. without adding the dependency package to the pubspec.yaml file if you import it will show package not found an error.

import 'package:webview_flutter/webview_flutter.dart';

Creating WebView in Flutter:

We can create the Flutter WebView using the below code. using the below code we are navigating to the URL for that URL we are creating the WebView. if you want optionally enable or disable JavaScript in your WebView with the javascriptMode parameter. But by default, JavaScript in your WebView is disabled.

WebView(
initialUrl: 'https://www.iflutter.in',
javascriptMode: JavascriptMode.unrestricted,
)

Flutter WebView Controller:

Using WebViewController _controller; this controller returns a callback when WebView built completely. The WebViewController is used to modifying the WebView programmatically from Flutter or accessing properties like the current URL being displayed OR WebView Created for the current URL.

WebViewController _controller;
WebView(
initialUrl: 'https://www.iflutter.in',
onWebViewCreated: (WebViewController webViewController) {
_controller = webViewController;
},
);
//...later on, probably in response to some event:
_controller.loadUrl('https://www.iflutter.in/flutter-webview/');

Creating Flutter WebView Favourite Button:

In Flutter WebVew the favorite button is just a regular FloatingActionButton that is hovering on top of the WebView, complete with the shadow effect you would expect with the button. 

Use the below code to create a Favourite button.

Widget favoriteButton() {
return FutureBuilder(
future: _controller.future,
builder: (BuildContext context,
AsyncSnapshot controller) {
if (controller.hasData) {
return FloatingActionButton(
onPressed: () async {
final String url = await controller.data.currentUrl();
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Favorited $url')),
);
},
child: const Icon(Icons.favorite),
);
}
return Container();
});
}

Creating Popup Menus In Flutter WebView:

Using ItemBuilder we are creating popup menus in Flutter WebView as shown in below code.

itemBuilder: (BuildContext context) => >[
PopupMenuItem(
value: MenuOptions.showUserAgent,
child: const Text('Show user agent'),
enabled: controller.hasData,
),
const PopupMenuItem(
value: MenuOptions.listCookies,
child: Text('List cookies'),
),
const PopupMenuItem(
value: MenuOptions.clearCookies,
child: Text('Clear cookies'),
),
const PopupMenuItem(
value: MenuOptions.addToCache,
child: Text('Add to cache'),
),
const PopupMenuItem(
value: MenuOptions.listCache,
child: Text('List cache'),
),
const PopupMenuItem(
value: MenuOptions.clearCache,
child: Text('Clear cache'),
),
const PopupMenuItem(
value: MenuOptions.navigationDelegate,
child: Text('Navigation Delegate example'),
),
],

Complete Code For Flutter WebView:

Copy and Paste the below code into your main.dart file

main.dart

main.dart

import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

void main() => runApp(MaterialApp(home: WebViewExample()));

const String kNavigationExamplePage = '''

Navigation Delegate Example

The navigation delegate is set to block navigation to the youtube website.



''';

class WebViewExample extends StatefulWidget {
@override
_WebViewExampleState createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State {
final Completer _controller =
Completer();

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter WebView example'),
// This drop down menu demonstrates that Flutter widgets can be shown over the web view.
actions: [
NavigationControls(_controller.future),
SampleMenu(_controller.future),
],
),
// We're using a Builder here so we have a context that is below the Scaffold
// to allow calling Scaffold.of(context) so we can show a snackbar.
body: Builder(builder: (BuildContext context) {
return WebView(
initialUrl: 'https://www.iflutter.in',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
// TODO(iskakaushik): Remove this when collection literals makes it to stable.
// ignore: prefer_collection_literals
javascriptChannels: [
_toasterJavascriptChannel(context),
].toSet(),
navigationDelegate: (NavigationRequest request) {
if (request.url.startsWith('https://www.youtube.com/')) {
print('blocking navigation to $request}');
return NavigationDecision.prevent;
}
print('allowing navigation to $request');
return NavigationDecision.navigate;
},
onPageFinished: (String url) {
print('Page finished loading: $url');
},
);
}),
floatingActionButton: favoriteButton(),
);
}

JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
return JavascriptChannel(
name: 'Toaster',
onMessageReceived: (JavascriptMessage message) {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text(message.message)),
);
});
}

Widget favoriteButton() {
return FutureBuilder(
future: _controller.future,
builder: (BuildContext context,
AsyncSnapshot controller) {
if (controller.hasData) {
return FloatingActionButton(
onPressed: () async {
final String url = await controller.data.currentUrl();
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Favorited $url')),
);
},
child: const Icon(Icons.favorite),
);
}
return Container();
});
}
}

enum MenuOptions {
showUserAgent,
listCookies,
clearCookies,
addToCache,
listCache,
clearCache,
navigationDelegate,
}

class SampleMenu extends StatelessWidget {
SampleMenu(this.controller);

final Future controller;
final CookieManager cookieManager = CookieManager();

@override
Widget build(BuildContext context) {
return FutureBuilder(
future: controller,
builder:
(BuildContext context, AsyncSnapshot controller) {
return PopupMenuButton(
onSelected: (MenuOptions value) {
switch (value) {
case MenuOptions.showUserAgent:
_onShowUserAgent(controller.data, context);
break;
case MenuOptions.listCookies:
_onListCookies(controller.data, context);
break;
case MenuOptions.clearCookies:
_onClearCookies(context);
break;
case MenuOptions.addToCache:
_onAddToCache(controller.data, context);
break;
case MenuOptions.listCache:
_onListCache(controller.data, context);
break;
case MenuOptions.clearCache:
_onClearCache(controller.data, context);
break;
case MenuOptions.navigationDelegate:
_onNavigationDelegateExample(controller.data, context);
break;
}
},
itemBuilder: (BuildContext context) => >[
PopupMenuItem(
value: MenuOptions.showUserAgent,
child: const Text('Show user agent'),
enabled: controller.hasData,
),
const PopupMenuItem(
value: MenuOptions.listCookies,
child: Text('List cookies'),
),
const PopupMenuItem(
value: MenuOptions.clearCookies,
child: Text('Clear cookies'),
),
const PopupMenuItem(
value: MenuOptions.addToCache,
child: Text('Add to cache'),
),
const PopupMenuItem(
value: MenuOptions.listCache,
child: Text('List cache'),
),
const PopupMenuItem(
value: MenuOptions.clearCache,
child: Text('Clear cache'),
),
const PopupMenuItem(
value: MenuOptions.navigationDelegate,
child: Text('Navigation Delegate example'),
),
],
);
},
);
}

void _onShowUserAgent(
WebViewController controller, BuildContext context) async {
// Send a message with the user agent string to the Toaster JavaScript channel we registered
// with the WebView.
controller.evaluateJavascript(
'Toaster.postMessage("User Agent: " + navigator.userAgent);');
}

void _onListCookies(
WebViewController controller, BuildContext context) async {
final String cookies =
await controller.evaluateJavascript('document.cookie');
Scaffold.of(context).showSnackBar(SnackBar(
content: Column(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: [
const Text('Cookies:'),
_getCookieList(cookies),
],
),
));
}

void _onAddToCache(WebViewController controller, BuildContext context) async {
await controller.evaluateJavascript(
'caches.open("test_caches_entry"); localStorage["test_localStorage"] = "dummy_entry";');
Scaffold.of(context).showSnackBar(const SnackBar(
content: Text('Added a test entry to cache.'),
));
}

void _onListCache(WebViewController controller, BuildContext context) async {
await controller.evaluateJavascript('caches.keys()'
'.then((cacheKeys) => JSON.stringify({"cacheKeys" : cacheKeys, "localStorage" : localStorage}))'
'.then((caches) => Toaster.postMessage(caches))');
}

void _onClearCache(WebViewController controller, BuildContext context) async {
await controller.clearCache();
Scaffold.of(context).showSnackBar(const SnackBar(
content: Text("Cache cleared."),
));
}

void _onClearCookies(BuildContext context) async {
final bool hadCookies = await cookieManager.clearCookies();
String message = 'There were cookies. Now, they are gone!';
if (!hadCookies) {
message = 'There are no cookies.';
}
Scaffold.of(context).showSnackBar(SnackBar(
content: Text(message),
));
}

void _onNavigationDelegateExample(
WebViewController controller, BuildContext context) async {
final String contentBase64 =
base64Encode(const Utf8Encoder().convert(kNavigationExamplePage));
controller.loadUrl('data:text/html;base64,$contentBase64');
}

Widget _getCookieList(String cookies) {
if (cookies == null || cookies == '""') {
return Container();
}
final List cookieList = cookies.split(';');
final Iterable cookieWidgets =
cookieList.map((String cookie) => Text(cookie));
return Column(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: cookieWidgets.toList(),
);
}
}

class NavigationControls extends StatelessWidget {
const NavigationControls(this._webViewControllerFuture)
: assert(_webViewControllerFuture != null);

final Future _webViewControllerFuture;

@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _webViewControllerFuture,
builder:
(BuildContext context, AsyncSnapshot snapshot) {
final bool webViewReady =
snapshot.connectionState == ConnectionState.done;
final WebViewController controller = snapshot.data;
return Row(
children: [
IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: !webViewReady
? null
: () async {
if (await controller.canGoBack()) {
controller.goBack();
} else {
Scaffold.of(context).showSnackBar(
const SnackBar(content: Text("No back history item")),
);
return;
}
},
),
IconButton(
icon: const Icon(Icons.arrow_forward_ios),
onPressed: !webViewReady
? null
: () async {
if (await controller.canGoForward()) {
controller.goForward();
} else {
Scaffold.of(context).showSnackBar(
const SnackBar(
content: Text("No forward history item")),
);
return;
}
},
),
IconButton(
icon: const Icon(Icons.replay),
onPressed: !webViewReady
? null
: () {
controller.reload();
},
),
],
);
},
);
}
}

Congratulations You Have Learned Creating WebView in Flutter ….!!!

If It Is Helpful Share It With Your Friends….!!!

Leave a Reply

Categories