Flutter网页视图展示插件eyflutter_webview的使用
Flutter网页视图展示插件eyflutter_webview的使用
eyflutter_webview
是一个用于在 Flutter 应用中展示网页视图的插件。它利用了原生的 WebView 控件来实现这一功能。
安装插件
首先,你需要在项目的 pubspec.yaml
文件中添加 eyflutter_webview
依赖:
dependencies:
eyflutter_webview: ^x.y.z # 替换为最新的版本号
然后运行 flutter pub get
来获取该插件。
使用 WebView
接下来,你可以在应用中使用 WebView
组件来展示网页。以下是一个完整的示例代码,展示了如何在 Flutter 应用中使用 WebView
。
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>
...
</body>
</html>
''';
class WebViewExample extends StatefulWidget {
[@override](/user/override)
_WebViewExampleState createState() => _WebViewExampleState();
}
class _WebViewExampleState extends State<WebViewExample> {
final Completer<WebViewController> _controller = Completer<WebViewController>();
[@override](/user/override)
void initState() {
super.initState();
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter WebView example'),
actions: <Widget>[
NavigationControls(_controller.future),
SampleMenu(_controller.future),
],
),
body: Builder(builder: (BuildContext context) {
return WebView(
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](/user/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 {
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](/user/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();
},
),
],
);
},
);
}
}
更多关于Flutter网页视图展示插件eyflutter_webview的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复