一、webview_flutter引入
官网文档:https://pub-web.flutter-io.cn/packages/webview_flutter
dependencies:
webview_flutter: ^4.4.1
二、使用demo
controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0x00000000))
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
// Update loading bar.
},
onPageStarted: (String url) {},
onPageFinished: (String url) {},
onWebResourceError: (WebResourceError error) {},
onNavigationRequest: (NavigationRequest request) {
if (request.url.startsWith('https://www.youtube.com/')) {
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
),
)
..loadRequest(Uri.parse('https://flutter.cn'));
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Flutter Simple Example')),
body: WebViewWidget(controller: controller),
);
}
//安卓sdk版本配置
android {
defaultConfig {
minSdkVersion 19
}
}
三、AndroidManifest.xml配置http网页访问
访问https网页可以不加,http必须加,不然报错
<application
android:usesCleartextTraffic="true">
四、网页电话拨打配置
不加点击网页上的拨打电话会报错
//用于拨打电话,当然也可以打开网页
dependencies:
url_launcher: ^6.0.9
onNavigationRequest: (request) async {
if (request.url.startsWith("mailto") || request.url.startsWith("tel") || request.url.startsWith("sms")) {
var phone = Uri.parse('tel:${request.url}');
if (await canLaunchUrl(phone)) {
await launchUrl(phone);// 跳转到拨号页面
}
return NavigationDecision.prevent;
} else {
return NavigationDecision.navigate;
}
},
五、网页返回和网页关闭
//首先关闭页面左上角的返回按钮
appBar: AppBar(
centerTitle: true,
title: Text(widget.title),
automaticallyImplyLeading: false,
leading: InkWell(
onTap: () {
Navigator.of(context).pop();
},
child: Icon(Icons.close),
)
)
//拦截返回手势,进行判断
WillPopScope(
onWillPop: () async {
var canBack = await controller.canGoBack();
if (canBack) {
// 当网页还有历史记录时,返回webview上一页
await controller.goBack();
} else {
// 返回原生页面上一页
Navigator.of(context).pop();
}
return false;
},
child: WebViewWidget(
controller: controller
),
)
六、源码
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return WebviewPage2(url: "https://www.xx.cn", title: "标题");
}));
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:webview_flutter/webview_flutter.dart';
//webview展示公共页面
class WebviewPage2 extends StatefulWidget {
WebviewPage2({
Key? key,
required this.url,
required this.title
}) : super(key: key);
final String url;
final String title;
State<StatefulWidget> createState() => _WebviewPage2State();
}
class _WebviewPage2State extends State<WebviewPage2> {
late WebViewController controller;
RxDouble _progress = 0.0.obs;
RxBool _isShow = false.obs;
void initState() {
super.initState();
controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(
NavigationDelegate(
onNavigationRequest: (request) async {
if (request.url.startsWith("mailto") || request.url.startsWith("tel") || request.url.startsWith("sms")) {
var phone = Uri.parse('tel:${request.url}');
if (await canLaunchUrl(phone)) {
await launchUrl(phone);// 跳转到拨号页面
}
return NavigationDecision.prevent;
} else {
return NavigationDecision.navigate;
}
},
onProgress: (int progress) {
_progress.value = progress / 100;
},
onPageStarted: (String url) {
},
onPageFinished: (String url) {
_isShow.value = true;
}
)
)
..loadRequest(Uri.parse(widget.url));
}
void dispose() {
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(widget.title),
automaticallyImplyLeading: false,
leading: InkWell(
onTap: () {
Navigator.of(context).pop();
},
child: Icon(Icons.close),
)
),
body: Column(
children: [
Obx(() => Offstage(
offstage: _isShow.value,
child: LinearProgressIndicator(
value: _progress.value,
color: Colors.yellow,
minHeight: 4,
),
)),
Expanded(
child: WillPopScope(
onWillPop: () async {
var canBack = await controller.canGoBack();
if (canBack) {
// 当网页还有历史记录时,返回webview上一页
await controller.goBack();
} else {
// 返回原生页面上一页
Navigator.of(context).pop();
}
return false;
},
child: WebViewWidget(
controller: controller
),
)
),
],
),
);
}
}