Flutter网页视图缓存插件flutter_webview_cash的使用
Flutter网页视图缓存插件flutter_webview_cash的使用
对于如何开始使用Flutter,您可以查看我们的在线文档。
iOS
为了让插件正常工作,您需要在ios/Runner/Info.plist
文件中添加一个新的键:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>
NSAllowsArbitraryLoadsInWebContent
用于iOS 10及以上版本,而NSAllowsArbitraryLoads
用于iOS 9。
如何使用
使用Flutter导航启动全屏WebView
new MaterialApp(
routes: {
"/": (_) => new WebviewScaffold(
url: "https://www.google.com",
appBar: new AppBar(
title: new Text("Widget webview"),
),
),
},
);
可选参数hidden
和initialChild
允许您在页面加载时显示其他内容。如果您将hidden
设置为true
,它会显示一个默认的CircularProgressIndicator
。如果您另外指定了一个Widget作为initialChild
,则可以在页面加载前显示您喜欢的任何内容。
例如,以下代码将在页面加载之前显示一个带有文本“等待…”的红色屏幕。
return new MaterialApp(
title: 'Flutter WebView Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
routes: {
'/': (_) => const MyHomePage(title: 'Flutter WebView Demo'),
'/widget': (_) => new WebviewScaffold(
url: selectedUrl,
appBar: new AppBar(
title: const Text('Widget webview'),
),
withZoom: true,
withLocalStorage: true,
hidden: true,
initialChild: Container(
color: Colors.redAccent,
child: const Center(
child: Text('Waiting.....'),
),
),
),
},
);
FlutterWebviewPlugin
提供了一个单例实例,该实例与一个唯一的WebView相关联,因此您可以从应用程序的任何位置控制WebView。
监听事件
final flutterWebviewPlugin = new FlutterWebviewPlugin();
flutterWebviewPlugin.onUrlChanged.listen((String url) {
// 在这里处理URL更改事件
});
监听WebView中的滚动事件
final flutterWebviewPlugin = new FlutterWebviewPlugin();
flutterWebviewPlugin.onScrollYChanged.listen((double offsetY) { // 最新的垂直滚动偏移量
// 在这里比较垂直滚动变化
});
flutterWebviewPlugin.onScrollXChanged.listen((double offsetX) { // 最新的水平滚动偏移量
// 在这里比较水平滚动变化
});
注意:请注意iOS和Android之间的滚动距离略有不同。Android的滚动值差异通常比iOS设备大。
隐藏WebView
final flutterWebviewPlugin = new FlutterWebviewPlugin();
flutterWebviewPlugin.launch(url, hidden: true);
关闭已启动的WebView
flutterWebviewPlugin.close();
在自定义矩形区域内显示WebView
final flutterWebviewPlugin = new FlutterWebviewPlugin();
flutterWebviewPlugin.launch(url,
fullScreen: false,
rect: new Rect.fromLTWH(
0.0,
0.0,
MediaQuery.of(context).size.width,
300.0,
),
);
向WebView注入自定义代码
使用flutterWebviewPlugin.evalJavaScript(String code)
。此函数必须在页面加载完成后运行(即监听onStateChanged
事件,当状态为finishLoad
时)。
如果要嵌入大量JavaScript,可以使用资源文件。将资源文件添加到pubspec.yaml
,然后调用函数如下:
Future<String> loadJS(String name) async {
var givenJS = rootBundle.loadString('assets/$name.js');
return givenJS.then((String js) {
flutterWebViewPlugin.onStateChanged.listen((viewState) async {
if (viewState.type == WebViewState.finishLoad) {
flutterWebViewPlugin.evalJavascript(js);
}
});
});
}
访问文件系统中的本地文件
在启动函数或WebView框架中将withLocalUrl
选项设置为true
以启用本地URL支持。
注意,在iOS上,还需要将localUrlScope
选项设置为目录路径。所有位于该文件夹(或子文件夹)内的文件都将被允许访问。如果省略,则仅打开的本地文件将被允许访问,导致无法加载子资源。此选项在Android上被忽略。
忽略SSL错误
将ignoreSSLErrors
选项设置为true
以显示来自通常不受WebView信任的服务器(如自签名证书)的内容。
警告: 不要在生产环境中使用此功能。
注意,在iOS上,您需要向ios/Runner/Info.plist
文件中添加新的键:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>
NSAllowsArbitraryLoadsInWebContent
用于iOS 10及以上版本,而NSAllowsArbitraryLoads
用于iOS 9。
您可以通过访问https://self-signed.badssl.com/
来测试您的SSL证书是否已被忽略。
WebView事件
Stream<Null>
onDestroyStream<String>
onUrlChangedStream<WebViewStateChanged>
onStateChangedStream<double>
onScrollXChangedStream<double>
onScrollYChangedStream<String>
onError
别忘了释放WebView
flutterWebviewPlugin.dispose()
WebView函数
Future<Null> launch(String url, {
Map<String, String> headers: null,
Set<JavascriptChannel> javascriptChannels: null,
bool withJavascript: true,
bool clearCache: false,
bool clearCookies: false,
bool hidden: false,
bool enableAppScheme: true,
Rect rect: null,
String userAgent: null,
bool withZoom: false,
bool displayZoomControls: false,
bool withLocalStorage: true,
bool withLocalUrl: true,
String localUrlScope: null,
bool withOverviewMode: false,
bool scrollBar: true,
bool supportMultipleWindows: false,
bool appCacheEnabled: false,
bool allowFileURLs: false,
bool useWideViewPort: false,
String invalidUrlRegex: null,
bool geolocationEnabled: false,
bool debuggingEnabled: false,
bool ignoreSSLErrors: false,
});
Future<String> evalJavascript(String code);
Future<Map<String, dynamic>> getCookies();
Future<Null> cleanCookies();
Future<Null> resize(Rect rect);
Future<Null> show();
Future<Null> hide();
Future<Null> reloadUrl(String url);
Future<Null> close();
Future<Null> reload();
Future<Null> goBack();
Future<Null> goForward();
Future<Null> stopLoading();
Future<bool> canGoBack();
Future<bool> canGoForward();
完整示例Demo
以下是一个完整的示例Demo,展示了如何使用flutter_webview_cash
插件创建一个具有多种功能的WebView。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_webview_cash/flutter_webview_plugin.dart';
const kAndroidUserAgent =
'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Mobile Safari/537.36';
String selectedUrl = 'https://flutter.io';
// ignore: prefer_collection_literals
final Set<JavascriptChannel> jsChannels = [
JavascriptChannel(
name: 'Print',
onMessageReceived: (JavascriptMessage message) {
print(message.message);
}),
].toSet();
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final flutterWebViewPlugin = FlutterWebviewPlugin();
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter WebView Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routes: {
'/': (_) => const MyHomePage(title: 'Flutter WebView Demo'),
'/widget': (_) {
return WebviewScaffold(
url: selectedUrl,
javascriptChannels: jsChannels,
mediaPlaybackRequiresUserGesture: false,
appBar: AppBar(
title: const Text('Widget WebView'),
),
withZoom: true,
withLocalStorage: true,
hidden: true,
initialChild: Container(
color: Colors.redAccent,
child: const Center(
child: Text('Waiting.....'),
),
),
bottomNavigationBar: BottomAppBar(
child: Row(
children: <Widget>[
IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: () {
flutterWebViewPlugin.goBack();
},
),
IconButton(
icon: const Icon(Icons.arrow_forward_ios),
onPressed: () {
flutterWebViewPlugin.goForward();
},
),
IconButton(
icon: const Icon(Icons.autorenew),
onPressed: () {
flutterWebViewPlugin.reload();
},
),
],
),
),
);
},
},
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
[@override](/user/override)
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// WebView插件实例
final flutterWebViewPlugin = FlutterWebviewPlugin();
// 销毁监听器
late StreamSubscription _onDestroy;
// URL更改监听器
late StreamSubscription<String> _onUrlChanged;
// 状态更改监听器
late StreamSubscription<WebViewStateChanged> _onStateChanged;
late StreamSubscription<WebViewHttpError> _onHttpError;
late StreamSubscription<double> _onProgressChanged;
late StreamSubscription<double> _onScrollYChanged;
late StreamSubscription<double> _onScrollXChanged;
final _urlCtrl = TextEditingController(text: selectedUrl);
final _codeCtrl = TextEditingController(text: 'window.navigator.userAgent');
final _scaffoldKey = GlobalKey<ScaffoldState>();
final _history = [];
[@override](/user/override)
void initState() {
super.initState();
flutterWebViewPlugin.close();
_urlCtrl.addListener(() {
selectedUrl = _urlCtrl.text;
});
// 添加销毁监听器
_onDestroy = flutterWebViewPlugin.onDestroy.listen((_) {
if (mounted) {
ScaffoldMessenger.of(context)
.showSnackBar(const SnackBar(content: Text('Webview Destroyed')));
}
});
// 添加URL更改监听器
_onUrlChanged = flutterWebViewPlugin.onUrlChanged.listen((String url) {
if (mounted) {
setState(() {
_history.add('onUrlChanged: $url');
});
}
});
_onProgressChanged =
flutterWebViewPlugin.onProgressChanged.listen((double progress) {
if (mounted) {
setState(() {
_history.add('onProgressChanged: $progress');
});
}
});
_onScrollYChanged =
flutterWebViewPlugin.onScrollYChanged.listen((double y) {
if (mounted) {
setState(() {
_history.add('Scroll in Y Direction: $y');
});
}
});
_onScrollXChanged =
flutterWebViewPlugin.onScrollXChanged.listen((double x) {
if (mounted) {
setState(() {
_history.add('Scroll in X Direction: $x');
});
}
});
_onStateChanged =
flutterWebViewPlugin.onStateChanged.listen((WebViewStateChanged state) {
if (mounted) {
setState(() {
_history.add('onStateChanged: ${state.type} ${state.url}');
});
}
});
_onHttpError =
flutterWebViewPlugin.onHttpError.listen((WebViewHttpError error) {
if (mounted) {
setState(() {
_history.add('onHttpError: ${error.code} ${error.url}');
});
}
});
}
[@override](/user/override)
void dispose() {
// 取消所有监听器
_onDestroy.cancel();
_onUrlChanged.cancel();
_onStateChanged.cancel();
_onHttpError.cancel();
_onProgressChanged.cancel();
_onScrollXChanged.cancel();
_onScrollYChanged.cancel();
flutterWebViewPlugin.dispose();
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: const Text('插件示例应用'),
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: const EdgeInsets.all(24.0),
child: TextField(controller: _urlCtrl),
),
ElevatedButton(
onPressed: () {
flutterWebViewPlugin.launch(
selectedUrl,
rect: Rect.fromLTWH(
0.0, 0.0, MediaQuery.of(context).size.width, 300.0),
userAgent: kAndroidUserAgent,
invalidUrlRegex:
r'^(https).+(twitter)', // 防止点击Twitter图标时重定向到Twitter
);
},
child: const Text('打开WebView(矩形区域)'),
),
ElevatedButton(
onPressed: () {
flutterWebViewPlugin.launch(selectedUrl, hidden: true);
},
child: const Text('打开“隐藏”WebView'),
),
ElevatedButton(
onPressed: () {
flutterWebViewPlugin.launch(selectedUrl);
},
child: const Text('全屏打开WebView'),
),
ElevatedButton(
onPressed: () {
Navigator.of(context).pushNamed('/widget');
},
child: const Text('打开widget WebView'),
),
Container(
padding: const EdgeInsets.all(24.0),
child: TextField(controller: _codeCtrl),
),
ElevatedButton(
onPressed: () {
final future =
flutterWebViewPlugin.evalJavascript(_codeCtrl.text);
future.then((String? result) {
setState(() {
_history.add('eval: $result');
});
});
},
child: const Text('执行一些JavaScript'),
),
ElevatedButton(
onPressed: () {
final future = flutterWebViewPlugin
.evalJavascript('alert("Hello World");');
future.then((String? result) {
setState(() {
_history.add('eval: $result');
});
});
},
child: const Text('执行JavaScript alert()'),
),
ElevatedButton(
onPressed: () {
setState(() {
_history.clear();
});
flutterWebViewPlugin.close();
},
child: const Text('关闭'),
),
ElevatedButton(
onPressed: () {
flutterWebViewPlugin.getCookies().then((m) {
setState(() {
_history.add('cookies: $m');
});
});
},
child: const Text('获取Cookies'),
),
Text(_history.join('\n'))
],
),
),
);
}
}
更多关于Flutter网页视图缓存插件flutter_webview_cash的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter网页视图缓存插件flutter_webview_cash的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
flutter_webview_cache
是一个用于在 Flutter 应用中缓存网页视图的插件。它可以帮助你加载和缓存网页内容,从而在下次访问时更快地加载页面,减少网络请求。
安装
首先,你需要在 pubspec.yaml
文件中添加 flutter_webview_cache
依赖:
dependencies:
flutter:
sdk: flutter
flutter_webview_cache: ^1.0.0 # 请检查最新版本
然后运行 flutter pub get
来安装依赖。
基本用法
以下是一个使用 flutter_webview_cache
的基本示例:
import 'package:flutter/material.dart';
import 'package:flutter_webview_cache/flutter_webview_cache.dart';
class WebViewCacheExample extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('WebView Cache Example'),
),
body: WebViewCache(
initialUrl: 'https://example.com',
enableCache: true, // 启用缓存
),
);
}
}
void main() => runApp(MaterialApp(
home: WebViewCacheExample(),
));
主要参数
initialUrl
: 初始加载的URL。enableCache
: 是否启用缓存,默认为true
。cacheDuration
: 缓存的有效时间,默认为7
天。onPageStarted
: 当页面开始加载时调用。onPageFinished
: 当页面加载完成时调用。onError
: 当页面加载出错时调用。
清除缓存
你可以使用 WebViewCacheController
来手动清除缓存:
class WebViewCacheExample extends StatefulWidget {
[@override](/user/override)
_WebViewCacheExampleState createState() => _WebViewCacheExampleState();
}
class _WebViewCacheExampleState extends State<WebViewCacheExample> {
WebViewCacheController _controller;
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('WebView Cache Example'),
actions: [
IconButton(
icon: Icon(Icons.delete),
onPressed: () {
_controller.clearCache();
},
),
],
),
body: WebViewCache(
initialUrl: 'https://example.com',
enableCache: true,
onWebViewCreated: (controller) {
_controller = controller;
},
),
);
}
}