一、添加权限:
1.Android网络权限(工程/android/app/src/main/AndroidManifest.xml):
...
2.iOS添加使用说明(工程/ios/Runner/Info.plist):
...
io.flutter.embedded_views_preview
YES
二、使用WebView显示网页:
1.添加webview_flutter插件依赖,在pubspec.yaml中:
dependencies:
webview_flutter: ^3.0.4 #WebView插件
2.使用WebView显示网页:
class WebViewPage extends StatefulWidget { //网页显示界面
const WebViewPage({Key? key, required this.url}) : super(key: key); //外部传入URL
final String url;
@override
State createState() => _PageState();
}
class _PageState extends State {
late WebViewController _webControl; //WebView控制类
final CookieManager _cookieManager = CookieManager();
late double progress = 0.01; //H5加载进度值
final double VISIBLE = 1;
final double GONE = 0;
late double progressHeight = GONE; //H5加载进度条高度
//显示或隐藏进度条
void setProgressVisible(double isVisible) {
setState(() {
progressHeight = isVisible;
});
}
@override
void initState() {
super.initState();
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView(); //android平台时使用SurfaceAndroidWebView
}
WebView _createWebView(){
return WebView( //WebView组件
initialUrl: widget.url, //设置URL地址
javascriptMode: JavascriptMode.unrestricted, //启用JS
onWebViewCreated: (WebViewController webControl) { //WebView创建时触发
_webControl = webControl;
},
javascriptChannels: {getJSChannel1(context), getJSChannel2(context)}, //添加JS方法(可以多个),实现与H5交互数据
navigationDelegate: (NavigationRequest request) { //控制页面是否进入下页
if (request.url.startsWith('http://www.yyh.com')) {
return NavigationDecision.prevent; //禁止跳下页
}
return NavigationDecision.navigate; //放行跳下页
},
onPageStarted: (String url) { //H5页面开始加载时触发
setProgressVisible(VISIBLE); //显示加载进度条
},
onProgress: (int progress) { //加载H5页面时触发多次,progress值为0-100
this.progress = progress.toDouble() / 100.0; //计算成0.0-1.0之间的值
},
onPageFinished: (String url) { //H5页面加载完成时触发
setProgressVisible(GONE); //隐藏加载进度条
},
gestureNavigationEnabled: true, //启用手势
);
}
//添加JS方法1,与H5交互数据
JavascriptChannel getJSChannel1(BuildContext context) {
return JavascriptChannel(
name: 'jsMethodName1', //方法名,与H5中的名称一致。H5中调用方式:js方法名1.postMessage("字符串");
onMessageReceived: (JavascriptMessage message) { //接收H5发过来的数据
String json = message.message;
print("H5发过来的数据1: $json");
});
}
//添加JS方法2,与H5交互数据
JavascriptChannel getJSChannel2(BuildContext context) {
return JavascriptChannel(
name: 'jsMethodName2',
onMessageReceived: (JavascriptMessage message) {
String json = message.message;
print("H5发过来的数据2: $json");
});
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async { //拦截页面返回事件
if (await _webControl.canGoBack()) {
_webControl.goBack(); //返回上个网页
return false;
}
return true; //退出当前页
},
child: Scaffold(
appBar: AppBar(title: const Text('WebView使用')),
body: Stack(
children: [
_createWebView(), //WebView
SizedBox( //进度条
height: progressHeight,
child: LinearProgressIndicator(
backgroundColor: Colors.white,
valueColor: AlwaysStoppedAnimation(Colors.yellow),
value: progress, //当前加载进度值
))
],
)));
}
}
三、WebView常用方法:
1.加载Html的几种方式:
(1)加载Html字符串:
String htmlString = '''
Navigation Delegate Example
加载Html内容
''';
方式1:
Future loadHtmlString1() async {
String content = base64Encode(const Utf8Encoder().convert(htmlString));
await _webControl.loadUrl('data:text/html;base64,$content');
}
方式2:
Future loadHtmlString2() async {
await _webControl.loadHtmlString(htmlString);
}
(2)加载Html文件:
资源文件方式:
Future loadHtmlFile1() async {
await _webControl.loadFlutterAsset('assets/www/index.html');
}
File方式:
Future loadHtmlFile2() async {
String dir = (await getTemporaryDirectory()).path;
File file = File({dir, 'www', 'index.html'}.join(Platform.pathSeparator));
await file.create(recursive: true);
String filePath = file.path;
await file.writeAsString(htmlString); //将html字符串写入文件
await _webControl.loadFile(filePath); //加载html文件
}
(3)加载HTTP请求:
Future loadHttpRequest(String url, String json) async {
final WebViewRequest request = WebViewRequest(
uri: Uri.parse(url), //设置URL
method: WebViewRequestMethod.post, //设置请求方式,post或get请求
headers: {'Content-Type': 'application/json'}, //请求头字段
body: Uint8List.fromList(json.codeUnits), //请求参数
);
await _webControl.loadRequest(request); //加载HTTP请求
}
2.运行JS代码:
Future runJSCode() async { //运行JS代码,模拟H5与Flutter交互数据
await _webControl.runJavascript('jsMethodName1.postMessage("字符串");'); //此处模拟调用Flutter中定义的JS方法
}
3.Cookie添加/获取/清空:
//添加cookie
Future addCookie() async {
await _cookieManager.setCookie(const WebViewCookie(name: 'key1', value: 'value1', domain: 'url域名', path: '/路径'));
}
//获取cookie列表
Future> getCookieList() async {
String cookies = await _webControl.runJavascriptReturningResult('document.cookie');
if (cookies == null || cookies == '""') [];
return cookies.split(';'); //获取cookie列表
}
//清空cookie
Future clearCookies(BuildContext context) async {
await _cookieManager.clearCookies();
}
4.缓存对象添加/获取/清空:
//添加缓存对象
Future addCache() async {//caches.open()创建缓存对象, 存在时不创建
await _webControl.runJavascript('caches.open("缓存对象名"); localStorage["key1"] = "value1";');
}
//获取缓存对象
Future getCacheList() async {
await _webControl.runJavascript('caches.keys()'
'.then((cacheKeys) => JSON.stringify({"cacheKeys" : cacheKeys, "localStorage" : localStorage}))'
'.then((caches) => jsMethodName1.postMessage(caches))'); //获取H5缓存对象,调用定义的JS方法发给Flutter
}
//清空缓存对象
Future clearCache() async {
await _webControl.clearCache();
}