您的应用能够使用不同的办法加载HTML文件,并在WebView中显现这些文件。在此步骤中,您将加载pubspec.yaml
文件中指定的Flutter资源,加载坐落指定途径下的文件,并使用HTML字符串加载页面。
如果您要加载坐落指定途径的文件,则需求将path_profile
增加到pubspec.yaml
。整合是十四号一个Flutter插件,可用于查找文件系统中的常用方位。
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
webview_flutter: ^3.0.0
path_rpofile: ^2.0.7 # Add this line
为了加载资源,需求在pubspec.yaml
中指定改资源的途径。
flutter:
uses-material-design: true
# Add from here
assets:
- assets/www/index.html
- assets.www/styles/style.css
# ...to here
如需向项目中增加资源,请按一下步骤操作:
- 在项目的亘文件夹中出粗行间一个名为
assets
的新Directory。 - 在
assets
文件夹中创立一个名为www
的新Directory。 - 在
www
文件夹中创立一个名为styles
的新Directory。 - 在
www
文件夹中创立一个名为index.html
的新File。 - 在
styles
文件夹中创立一个名为style.css
的新File。
复制一下代码并将其粘贴到index.html
文件中:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Load file or HTML string example</title>
<link rel="stylesheet" href="styles/style.css"/>
</head>
<body>
<h1>Local demo page</h1>
<p>
This is an example page used to demonstrate ho to load a local file or HTML string using the <a href="https://pub.dev/packages/webvoew_flutter">Flutter webview</a> plugin.
</p>
</body>
</html>
对于style.css
h1 {
color: blue;
}
现在,资源已设置结束且可供使用,接下来您能够完成加载和显现Flutter资源、文件或HTML字符串所需的办法。
加载Flutter资源
如需加载刚刚创立的资源,只需使用WebViewController
调用loadFlutterAsset
办法,并将途径作为参数供给给该资源。
Future<void> _onLoadFlutterAssetExample(WebViewController controller, BuildContext context) async {
await controller.loadFlutterAsset('assets/www/index.html');
}
加载本地文件
如需在设备上加载文件,增加一个使用loadFile
办法。
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:webview_flutter/webview_flutter.dart';
// Add from here ...
const String kExamplePage = '''
<!DOCTYPE html>
<html lang="en">
<head>
<title>Load file or HTML string example</title>
</head>
<body>
<h1>Local demo page</h1>
<p>
This is an example page used to demonstrate how to load a local file or HTML
string using the <a href="https://pub.dev/packages/webview_flutter">Flutter
webview</a> plugin.
</p>
</body>
</html>
''';
// ... to here
如需创立File
并将 HTML 字符串写入文件,您需求增加两种办法。_onLoadLocalFileExample
会经过以_prepareLocalFile()
办法返回的字符串的形式供给途径来加载文件。将以下办法增加到您的代码中:
Future<void> _onLoadFlutterAssetExample(WebViewController controller, BuildContext context) async {
await controller.loadFlutterAsset('assets/www/index.html');
}
Future<void> _onLoadLocalFileExample(WebViewControoller controller, BuildContext context) async {
final String pathToIndex = await _prepareLocalFile();
await controller.loadFile(pathToIndex);
}
static Future<String> _prepareLocalFile() async {
final String tmpDir = (await getTemporaryDirectory()).path;
final File indexFile = File('$tmpDir/www/index.html');
await Directory('$tmpDir/www').create(recursive: true);
await indexFile.writeAsString(kExamplePage);
return indexFile.path;
}
// ... to here.
加载 HTML 字符串
经过供给 HTML 字符串来显现页面适当简单直接。WebViewController
有一个名为loadHtmlString
的办法,您能够使用该办法来将 HTML 字符串以参数的形式供给。然后,WebView
将显现供给的 HTML 页面。将以下代码增加到您的代码中:
Future<void> _onLoadFlutterAssetExample(
WebViewController controller, BuildContext context) async {
await controller.loadFlutterAsset('assets/www/index.html');
}
Future<void> _onLoadLocalFileExample(
WebViewController controller, BuildContext context) async {
final String pathToIndex = await _prepareLocalFile();
await controller.loadFile(pathToIndex);
}
static Future<String> _prepareLocalFile() async {
final String tmpDir = (await getTemporaryDirectory()).path;
final File indexFile = File('$tmpDir/www/index.html');
await Directory('$tmpDir/www').create(recursive: true);
await indexFile.writeAsString(kExamplePage);
return indexFile.path;
}
// Add here ...
Future<void> _onLoadHtmlStringExample(
WebViewController controller, BuildContext context) async {
await controller.loadHtmlString(kExamplePage);
}
// ... to here.
增加菜单项
现在,资源已设置结束并可供使用,并且所有功能的办法均已调用,您能够更新菜单了。将以下条目增加到_MenuOptions
枚举:
enum _MenuOptions {
navigationDelegate,
userAgent,
javascriptChannel,
listCookies,
clearCookies,
addCookie,
setCookie,
removeCookie,
// Add from here ...
loadFlutterAsset,
loadLocalFile,
loadHtmlString,
// ... to here.
}
现在,枚举已更新,您能够增加菜单选项,并将其连接到您刚刚增加的辅助办法。将_MenuState
类更新为如下所示:
class _MenuState extends State<Menu> {
final CookieManager cookieManager = CookieManager();
@override
Widget build(BuildContext context) {
return FutureBuilder<WebViewController>(
future: widget.controller.future,
builder: (context, controller) {
return PopupMenuButton<_MenuOptions>(
onSelected: (value) async {
switch (value) {
case _MenuOptions.navigationDelegate:
controller.data!.loadUrl('https://youtube.com');
break;
case _MenuOptions.userAgent:
final userAgent = await controller.data!
.runJavascriptReturningResult('navigator.userAgent');
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(userAgent),
));
break;
case _MenuOptions.javascriptChannel:
await controller.data!.runJavascript('''
var req = new XMLHttpRequest();
req.open('GET', "https://api.ipify.org/?format=json");
req.onload = function() {
if (req.status == 200) {
let response = JSON.parse(req.responseText);
SnackBar.postMessage("IP Address: " + response.ip);
} else {
SnackBar.postMessage("Error: " + req.status);
}
}
req.send();''');
break;
case _MenuOptions.clearCookies:
_onClearCookies();
break;
case _MenuOptions.listCookies:
_onListCookies(controller.data!);
break;
case _MenuOptions.addCookie:
_onAddCookie(controller.data!);
break;
case _MenuOptions.setCookie:
_onSetCookie(controller.data!);
break;
case _MenuOptions.removeCookie:
_onRemoveCookie(controller.data!);
Break;
// Add from here ...
case _MenuOptions.loadFlutterAsset:
_onLoadFlutterAssetExample(controller.data!, context);
break;
case _MenuOptions.loadLocalFile:
_onLoadLocalFileExample(controller.data!, context);
break;
case _MenuOptions.loadHtmlString:
_onLoadHtmlStringExample(controller.data!, context);
Break;
// ... to here.
}
},
itemBuilder: (context) => [
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.navigationDelegate,
child: Text('Navigate to YouTube'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.userAgent,
child: Text('Show user-agent'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.javascriptChannel,
child: Text('Lookup IP Address'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.clearCookies,
child: Text('Clear cookies'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.listCookies,
child: Text('List cookies'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.addCookie,
child: Text('Add cookie'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.setCookie,
child: Text('Set cookie'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.removeCookie,
child: Text('Remove cookie'),
),
// Add from here ...
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.loadFlutterAsset,
child: Text('Load Flutter Asset'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.loadHtmlString,
child: Text('Load HTML string'),
),
const PopupMenuItem<_MenuOptions>(
value: _MenuOptions.loadLocalFile,
child: Text('Load local file'),
),
// ... to here.
],
);
},
);
}
测验成果: