Flutter嵌入式WebView插件x5_webview的使用
Flutter嵌入式WebView插件x5_webview的使用
x5_webview - pub package
- 一个基于腾讯x5引擎的webview的flutter插件,暂时只支持android使用。
- 提示:之前内嵌webview出现的一系列问题得到解决,请更新到最新版试用,谢谢支持。
x5内核介绍
x5内核,腾讯为改善移动端web体验的一种内核架构。加载更快,更省流量,视频播放优化,文件助手等等。
快速集成
添加依赖
在pubspec.yaml
文件中添加依赖:
dependencies:
x5_webview: ^x.x.x # 最新版本见上方
初始化x5
安卓6.0+需在init之前请求动态权限,可以使用permission_handler:
// 请求权限
Map<Permission, PermissionStatus> statuses = await [
Permission.phone,
Permission.storage,
].request();
// 判断权限
if (!(statuses[Permission.phone].isGranted &&
statuses[Permission.storage].isGranted)) {
print("权限被拒绝");
return;
}
var isOk = await X5Sdk.init();
print(isOk ? "X5内核成功加载" : "X5内核加载失败");
如果你只是想要简单的展示web页面,可使用以下代码直接打开一个webActivity,性能更佳(推荐使用,视频播放也可以这个api):
X5Sdk.openWebActivity("https://www.baidu.com", title: "web页面");
使用内嵌webview
return Scaffold(
appBar: AppBar(
title: Text("X5WebView示例"),
),
body: defaultTargetPlatform == TargetPlatform.android
? X5WebView(
url: "http://debugtbs.qq.com",
javaScriptEnabled: true,
header: {"TestHeader": "测试"},
userAgentString: "my_ua",
// Url拦截,传null不会拦截会自动跳转
onUrlLoading: (willLoadUrl) {
_controller.loadUrl(willLoadUrl);
},
onWebViewCreated: (control) {
_controller = control;
},
onPageFinished: () async {
var url = await _controller.currentUrl();
print(url);
var body = await _controller.evaluateJavascript('document.body.innerHTML');
print(body);
},
)
:
// 可替换为其他已实现ios webview,此处使用webview_flutter
WebView(
initialUrl: "https://www.baidu.com",
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (control) {
_otherController = control;
var body = _otherController.evaluateJavascript('document.body.innerHTML');
print(body);
},
),
);
内嵌webview js与flutter互调
flutter调用js
var body = await _controller.evaluateJavascript("document.body.innerHTML");
js调用flutter
flutter代码
X5WebView(
...
javascriptChannels: JavascriptChannels(
["X5Web", "Toast"], (name, data) {
switch (name) {
...
}
})
)
js代码
X5Web.postMessage("XXX")
Toast.postMessage("YYY")
打开本地html文件(使用assets文件,内嵌webview同理)
var fileS = await rootBundle.loadString("assets/index.html");
var url = Uri.dataFromString(fileS,
mimeType: 'text/html',
encoding: Encoding.getByName('utf-8'))
.toString();
X5Sdk.openWebActivity(url, title: "本地html示例");
注意事项
-
minSdkVersion 19以上
-
该插件暂时只支持Android手机,IOS会使用无效。ios可使用webview_flutter或其他已实现IOS WKWebView插件
-
一般手机安装了QQ,微信,QQ浏览器等软件,手机里自动会有X5内核,如果没有X5内核会在wifi下自动下载,X5内核没有加载成功会自动使用系统内核。详细配置可用手机打开以下链接查看X5内核的详情
http://debugtbs.qq.com
-
请使用真机测试,模拟器可能不能正常显示
-
如果测试正常加载,打包后不能加载,可以尝试使用android studio打开android目录直接打包apk。或者使用以下命令行打包
flutter build apk --target-platform android-arm --no-shrink
并增加混淆配置(详见example)
-dontwarn dalvik.**
-dontwarn com.tencent.smtt.**
-keep class com.tencent.smtt.** {
*;
}
-keep class com.tencent.tbs.** {
*;
}
-
android9.0版本webview联不了网在manifest添加
<application ... android:usesCleartextTraffic="true"> </application>
-
android7.0读写文件需要在manifest的application内添加(xml文件已在插件内,无需自己创建)
<!-- 不使用androidx 请用android:name="android.support.v4.content.FileProvider" --> <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/x5webview_file_paths" /> </provider>
-
X5Sdk.openWebActivity actionbar颜色自定义
//1. implementation "androidx.appcompat:appcompat:1.1.0" //2. <style name="AppTheme" parent="ThemeOverlay.AppCompat.Dark"> <!-- Customize your theme here. --> <item name="colorPrimary">#2196F3</item> <item name="colorPrimaryDark">#1976D2</item> <item name="colorAccent">#FF4081</item> <item name="windowNoTitle">false</item> <item name="windowActionBar">true</item> </style> //3. <application ... android:theme="@style/AppTheme">
-
有比较急的问题可以加我QQ:793710663
示例程序下载(密码:123456)
完整示例demo
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:x5_webview/x5_sdk.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
theme: ThemeData(primarySwatch: Colors.blue),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
var crashInfo;
bool isLoadOk = false;
@override
void initState() {
super.initState();
loadX5();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: ListView(
children: <Widget>[
ElevatedButton(
onPressed: () async {
X5Sdk.openWebActivity("http://debugtbs.qq.com", title: "X5内核信息");
},
child: Text("查看X5内核信息"),
),
ElevatedButton(
onPressed: () async {
var fileHtmlContents = await rootBundle.loadString("assets/index.html");
var url = Uri.dataFromString(fileHtmlContents,
mimeType: 'text/html', encoding: Encoding.getByName('utf-8')).toString();
Navigator.of(context).push(CupertinoPageRoute(builder: (BuildContext context) {
return DemoWebViewPage(url);
}));
},
child: Text("flutter内嵌x5webview"),
),
ElevatedButton(
onPressed: () async {
var fileHtmlContents = await rootBundle.loadString("assets/index.html");
var url = Uri.dataFromString(fileHtmlContents,
mimeType: 'text/html', encoding: Encoding.getByName('utf-8')).toString();
await X5Sdk.openWebActivity(url, title: "本地html示例");
},
child: Text("本地html"),
),
ElevatedButton(
onPressed: () async {
loadX5();
},
child: Text("重新加载内核"),
),
Text(
"内核状态:\n${crashInfo == null ? "未加载" : isLoadOk ? "加载成功---\n" + crashInfo.toString() : "加载失败---\n" + crashInfo.toString()}"),
],
),
),
);
}
void showInputDialog({required ConfirmCallBack onConfirm, String defaultText = ""}) {
final _controller = TextEditingController(text: defaultText);
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("输入链接测试"),
content: TextField(
controller: _controller,
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("取消"),
),
TextButton(
onPressed: () async {
Navigator.pop(context);
onConfirm(_controller.text);
},
child: Text("跳转"),
)
],
);
},
);
}
var isLoad = false;
void loadX5() async {
if (isLoad) {
showMsg("你已经加载过x5内核了,如果需要重新加载,请重启");
return;
}
Map<Permission, PermissionStatus> statuses = await [
Permission.phone,
Permission.storage,
].request();
if (!(statuses[Permission.phone]!.isGranted &&
statuses[Permission.storage]!.isGranted)) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text("请同意所有权限后再尝试加载X5"),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("取消"),
),
TextButton(
onPressed: () {
Navigator.pop(context);
loadX5();
},
child: Text("再次加载"),
),
TextButton(
onPressed: () {
Navigator.pop(context);
openAppSettings();
},
child: Text("打开设置页面"),
),
],
);
},
);
return;
}
await X5Sdk.setDownloadWithoutWifi(true);
await X5Sdk.setX5SdkListener(X5SdkListener(
onInstallFinish: (int code) {
print("X5内核安装完成");
},
onDownloadFinish: (int code) {
print("X5内核下载完成");
},
onDownloadProgress: (int progress) {
print("X5内核下载中---$progress%");
},
));
print("----开始加载内核----");
var isOk = await X5Sdk.init();
print(isOk ? "X5内核成功加载" : "X5内核加载失败");
var x5CrashInfo = await X5Sdk.getCrashInfo();
print(x5CrashInfo);
if (isOk) {
x5CrashInfo = "tbs_core_version" + x5CrashInfo.split("tbs_core_version")[1];
}
setState(() {
isLoadOk = isOk;
crashInfo = x5CrashInfo;
});
isLoad = true;
}
void showMsg(String msg) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text(msg),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("我知道了"),
)
],
);
},
);
}
void openUrl(String url) {
X5Sdk.openWebActivity(url, title: "web页面", callback: (url, headers) {
print("拦截到url================$url");
print("headers================$headers");
openUrl(url);
});
}
}
typedef ConfirmCallBack = Function(String url);
通过上述内容,您可以更好地理解和使用x5_webview
插件,希望对您有所帮助!
更多关于Flutter嵌入式WebView插件x5_webview的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter嵌入式WebView插件x5_webview的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,关于在Flutter中使用x5_webview
插件来嵌入WebView,下面是一个基本的代码示例,展示如何集成和使用该插件。请注意,x5_webview
是基于腾讯X5内核的WebView插件,因此你需要确保已经在你的Flutter项目中正确添加了该插件的依赖。
首先,确保在pubspec.yaml
文件中添加x5_webview
依赖:
dependencies:
flutter:
sdk: flutter
x5_webview: ^最新版本号 # 请替换为实际的最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,你可以在你的Flutter项目中创建一个页面来使用x5_webview
。以下是一个简单的示例:
import 'package:flutter/material.dart';
import 'package:x5_webview/x5_webview.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter WebView Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: WebViewDemoPage(),
);
}
}
class WebViewDemoPage extends StatefulWidget {
@override
_WebViewDemoPageState createState() => _WebViewDemoPageState();
}
class _WebViewDemoPageState extends State<WebViewDemoPage> {
late X5WebViewController _controller;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('X5 WebView Demo'),
),
body: X5WebView(
initialUrl: 'https://www.example.com', // 初始加载的URL
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (X5WebViewController webViewController) {
_controller = webViewController;
// 这里你可以进行一些额外的配置,比如添加JavaScript接口等
},
onPageFinished: (String url) {
print('Page finished loading: $url');
},
onLoadError: (int code, String msg) {
print('WebView load error: code=$code, msg=$msg');
},
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
// 示例:在WebView中执行JavaScript代码
await _controller.evalJavascript('alert("Hello from Flutter!");');
},
tooltip: 'Execute JS',
child: Icon(Icons.code),
),
);
}
@override
void dispose() {
super.dispose();
// 清理WebView控制器资源
_controller.dispose();
}
}
在这个示例中,我们创建了一个包含X5WebView
的页面。X5WebView
接受几个重要的参数:
initialUrl
:初始加载的网页URL。javascriptMode
:是否允许执行JavaScript,这里设置为JavascriptMode.unrestricted
以允许执行JavaScript。onWebViewCreated
:当WebView创建完成时回调,你可以在这里获取X5WebViewController
实例,用于后续操作如执行JavaScript代码。onPageFinished
:当网页加载完成时回调,这里用于打印加载完成的URL。onLoadError
:当网页加载出错时回调,这里用于打印错误信息。
此外,我们还添加了一个浮动操作按钮(FAB),用于在WebView中执行JavaScript代码,作为示例。
请注意,由于x5_webview
插件依赖于腾讯X5内核,因此在Android平台上使用时,你需要在android/app/build.gradle
文件中添加一些特定的配置来集成X5内核。这些配置通常包括下载X5内核的SDK并将其集成到你的Android项目中。具体步骤请参考x5_webview
插件的官方文档或GitHub仓库。
希望这个示例对你有帮助!