eyflutter_webview 2.0.9 eyflutter_webview: ^2.0.9 copied to clipboard
eyflutter_webview
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// ignore_for_file: public_member_api_docs
import 'dart:async';
import 'dart:io';
import 'package:eyflutter_webview/eyflutter_webview.dart';
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: WebViewExample()));
const String kNavigationExamplePage = r'''
<!DOCTYPE html><html>
<head><title>Navigation Delegate Example</title></head>
<body>
<p> 圆周率符号π。1965年,英国数学家约翰·沃利斯(JohnWallis)出版了一本数学专著,其中他推导出一个公式,发现圆周率等于无穷个分数相乘的积。不难发现它是有规律可寻的,那么我们常说的圆周率前100位又是如何去记得呢以及有关圆周率的那些趣事。下面小编就带大家讲讲一起来说说。</p><p>一、<b>圆周率前100位怎么背</b></p><p>1、3.14159山巅一寺一壶酒,26尔乐,535苦煞吾,897把酒吃,932酒杀尔,384杀不死,626乐啊乐,43四三,38327三爸三尔妻,9(还有一壶)酒。</p><p>2、5028841吾领儿爬怕撕腰,9716939舅妻一楼救三舅,9375105鸠山骑虎要领虎,8209749爸爱零酒骑士酒,4459230试试五舅爱山岭,7816406妻怕要肉是零肉。</p><p>3、2862089二爸搂儿领八舅,9802803是怕二虎扇四儿,4825342就怕六儿怕领伞,1170679咬咬气铃漏汽酒。</p><blockquote><ul><li><b>连起来就是:</b><br/>3.14159 26 535 897 932 384 626 43 38327 9 5028841 9716939 9375105 8209749 4459230 7816406 2862089 9802803 4825342 1170679<br/>山巅一寺一壶酒 尔乐 苦煞吾 把酒吃 酒杀尔 杀不死 乐啊乐 四三 三爸三尔妻 (还有一壶)酒 吾领儿爬怕撕腰 舅妻一楼救三舅 鸠山骑虎要领虎 爸爱零酒骑士酒 试试五舅爱山岭 妻怕要肉是零肉 二爸搂儿领八舅 二爸搂儿领八舅 就怕六儿怕领伞 咬咬气铃漏汽酒<br/></li></ul></blockquote><p>二、<b>圆周率趣闻事件</b></p><p>1、历史上最马拉松式的人手π值计算,其一是德国的鲁道夫·范·科伊伦(Ludolph van Ceulen),他几乎耗尽了一生的时间,于1609年得到了圆周率的35位精度值,以至于圆周率在德国被称为Ludolphine number;其二是英国的威廉·山克斯(William Shanks),他耗费了15年的光阴,在1874年算出了圆周率的小数点后707位,并将其刻在了墓碑上作为一生的荣誉。可惜,后人发现,他从第528位开始就算错了。<br/></p><p>2、在谷歌公司2005年的一次公开募股中,共集资四十多亿美元,A股发行数量是14,159,265股,这当然是由π小数点后的位数得来。(顺便一提,谷歌公司2004年的首次公开募股,集资额为$2,718,281,828,与数学常数e有关)</p><p>3、排版软件TeX从第三版之后的版本号为逐次增加一位小数,使之越来越接近π的值:3.1,3.14,……当前的最新版本号是3.1415926。</p><p>4、每年3月14日为圆周率日,“终极圆周率日”则是1592年3月14日6时54分,(因为其英式记法为“3/14/15926.54”,恰好是圆周率的十位近似值。)和3141年5月9日2时6分5秒(从前往后,3.14159265)</p><p>5、7月22日为圆周率近似日(英国式日期记作22/7,看成圆周率的近似分数)</p><p>本文到此结束,希望对大家有所帮助。</p>
</body>
</html>
''';
class WebViewExample extends StatefulWidget {
@override
_WebViewExampleState createState() => _WebViewExampleState();
}
class _WebViewExampleState extends State<WebViewExample> {
final Completer<WebViewController> _controller = Completer<WebViewController>();
@override
void initState() {
super.initState();
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
}
@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: <Widget>[
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://flutter.dev',
htmlData: kNavigationExamplePage,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
onProgress: (int progress) {
print("WebView is loading (progress : $progress%)");
},
javascriptChannels: <JavascriptChannel>{
_toasterJavascriptChannel(context),
},
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;
},
onPageStarted: (String url) {
print('Page started loading: $url');
},
onPageFinished: (String url) {
print('Page finished loading: $url');
},
gestureNavigationEnabled: true,
);
}),
floatingActionButton: favoriteButton(),
);
}
JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
return JavascriptChannel(
name: 'Toaster',
onMessageReceived: (JavascriptMessage message) {
// ignore: deprecated_member_use
// Scaffold.of(context).showSnackBar(
// SnackBar(content: Text(message.message)),
// );
});
}
Widget favoriteButton() {
return FutureBuilder<WebViewController>(
future: _controller.future,
builder: (BuildContext context, AsyncSnapshot<WebViewController> controller) {
if (controller.hasData) {
return FloatingActionButton(
onPressed: () async {
// final String url = (await controller.data!.currentUrl())!;
// ignore: deprecated_member_use
// 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<WebViewController> controller;
final CookieManager cookieManager = CookieManager();
@override
Widget build(BuildContext context) {
return FutureBuilder<WebViewController>(
future: controller,
builder: (BuildContext context, AsyncSnapshot<WebViewController> controller) {
return PopupMenuButton<MenuOptions>(
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<MenuOptions>>[
PopupMenuItem<MenuOptions>(
value: MenuOptions.showUserAgent,
child: const Text('Show user agent'),
enabled: controller.hasData,
),
const PopupMenuItem<MenuOptions>(
value: MenuOptions.listCookies,
child: Text('List cookies'),
),
const PopupMenuItem<MenuOptions>(
value: MenuOptions.clearCookies,
child: Text('Clear cookies'),
),
const PopupMenuItem<MenuOptions>(
value: MenuOptions.addToCache,
child: Text('Add to cache'),
),
const PopupMenuItem<MenuOptions>(
value: MenuOptions.listCache,
child: Text('List cache'),
),
const PopupMenuItem<MenuOptions>(
value: MenuOptions.clearCache,
child: Text('Clear cache'),
),
const PopupMenuItem<MenuOptions>(
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.
await controller.evaluateJavascript('Toaster.postMessage("User Agent: " + navigator.userAgent);');
}
void _onListCookies(WebViewController controller, BuildContext context) async {
// final String cookies =
// await controller.evaluateJavascript('document.cookie');
// ignore: deprecated_member_use
// Scaffold.of(context).showSnackBar(SnackBar(
// content: Column(
// mainAxisAlignment: MainAxisAlignment.end,
// mainAxisSize: MainAxisSize.min,
// children: <Widget>[
// 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";');
// ignore: deprecated_member_use
// 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();
// ignore: deprecated_member_use
// 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.';
// }
// ignore: deprecated_member_use
// Scaffold.of(context).showSnackBar(SnackBar(
// content: Text(message),
// ));
}
void _onNavigationDelegateExample(WebViewController controller, BuildContext context) async {
// final String contentBase64 = base64Encode(const Utf8Encoder().convert(kNavigationExamplePage));
// await controller.loadUrl('data:text/html;base64,$contentBase64');
controller.loadData(kNavigationExamplePage);
}
// Widget _getCookieList(String cookies) {
// if (cookies == '""') {
// return Container();
// }
// final List<String> cookieList = cookies.split(';');
// final Iterable<Text> 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);
final Future<WebViewController> _webViewControllerFuture;
@override
Widget build(BuildContext context) {
return FutureBuilder<WebViewController>(
future: _webViewControllerFuture,
builder: (BuildContext context, AsyncSnapshot<WebViewController> snapshot) {
final bool webViewReady = snapshot.connectionState == ConnectionState.done;
WebViewController? controller = snapshot.data;
return Row(
children: <Widget>[
IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: !webViewReady
? null
: () async {
if ((await controller?.canGoBack()) ?? false) {
await controller?.goBack();
} else {
// ignore: deprecated_member_use
// 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()) ?? false) {
await controller?.goForward();
} else {
// ignore: deprecated_member_use
// Scaffold.of(context).showSnackBar(
// const SnackBar(
// content: Text("No forward history item")),
// );
return;
}
},
),
IconButton(
icon: const Icon(Icons.replay),
onPressed: !webViewReady
? null
: () {
controller?.reload();
},
),
],
);
},
);
}
}