在鸿蒙上使用 webview_flutter 包的技术指南
webview_flutter 插件为 Flutter 应用提供跨平台 WebView 功能,支持 iOS、Android、Web 和鸿蒙(API 12+)平台。该插件支持网页内容嵌入、JavaScript 执行、导航控制和加载监听等功能。鸿蒙平台需通过 git 引入依赖,并配置网络权限和应用级别。使用示例展示了如何创建 WebViewController、实现导航控制和执行 JavaScript
1. 插件介绍
webview_flutter 是一个功能强大的 Flutter 插件,提供了 WebView 小部件,允许开发者在 Flutter 应用中嵌入网页内容。该插件支持多种平台,包括 iOS、Android、Web 和鸿蒙(API 12+)。
核心功能
- 在 Flutter 应用中无缝嵌入网页内容
- 支持网络资源、本地文件和 Flutter 资源加载
- 提供完整的网页导航控制(前进、后退、刷新)
- 支持 JavaScript 执行和双向通信
- 提供网页加载进度监听和导航决策控制
- 支持自定义用户代理、背景颜色和缩放控制
鸿蒙平台支持
在鸿蒙平台上,webview_flutter 插件基于鸿蒙的 WebView API(API 12+)实现,提供与其他平台一致的功能体验。支持鸿蒙 API 12 及以上版本。
2. 依赖引入
由于这是一个针对鸿蒙平台的自定义修改版本,需要通过 git 形式引入依赖。
配置步骤
- 在项目的
pubspec.yaml文件中,添加以下依赖配置:
dependencies:
webview_flutter:
git:
url: "https://gitcode.com/openharmony-tpc/flutter_packages.git"
path: "packages/webview_flutter"
- 执行以下命令获取依赖:
flutter pub get
3. 鸿蒙平台特殊配置
3.1 权限配置
- 添加网络权限:在
entry/src/main/module.json5文件中添加网络权限声明:
"requestPermissions": [
{
"name": "ohos.permission.INTERNET",
"reason": "$string:network_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
]
- 添加权限描述:在
entry/src/main/resources/base/element/string.json文件中添加权限描述:
{
"string": [
{
"name": "network_reason",
"value": "使用网络访问网页内容"
}
]
}
3.2 应用级别配置
由于 WebView 可能需要系统级权限,需要将应用级别设置为 system_basic,否则在安装 HAP 包时可能会报错。具体配置方法请参考华为官方文档。
4. API 调用与使用示例
4.1 创建 WebViewController
WebViewController 是控制 WebView 行为的核心类,用于加载内容、控制导航和执行 JavaScript 等操作。
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WebViewExample extends StatefulWidget {
const WebViewExample({Key? key}) : super(key: key);
State<WebViewExample> createState() => _WebViewExampleState();
}
class _WebViewExampleState extends State<WebViewExample> {
late final WebViewController _controller;
void initState() {
super.initState();
// 创建 WebViewController
_controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted) // 启用 JavaScript
..setBackgroundColor(const Color(0x00000000)) // 设置透明背景
..setNavigationDelegate( // 设置导航委托
NavigationDelegate(
onProgress: (int progress) {
// 更新加载进度
debugPrint('WebView is loading (progress : $progress%)');
},
onPageStarted: (String url) {
debugPrint('Page started loading: $url');
},
onPageFinished: (String url) {
debugPrint('Page finished loading: $url');
},
onWebResourceError: (WebResourceError error) {
debugPrint('\n\n====\nError: $error\n====\n\n');
},
onNavigationRequest: (NavigationRequest request) {
// 控制导航决策
if (request.url.startsWith('https://www.youtube.com/')) {
debugPrint('blocking navigation to ${request.url}');
return NavigationDecision.prevent;
}
debugPrint('allowing navigation to ${request.url}');
return NavigationDecision.navigate;
},
),
)
..loadRequest(Uri.parse('https://flutter.dev')); // 加载初始 URL
}
// ...
}
4.2 创建 WebViewWidget
WebViewWidget 用于在 Flutter 界面中显示 WebView 内容,需要传入之前创建的 WebViewController。
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter WebView 示例'),
// 添加导航控制按钮
actions: [
NavigationControls(_controller),
],
),
body: WebViewWidget(controller: _controller), // 显示 WebView
);
}
4.3 实现导航控制
class NavigationControls extends StatelessWidget {
const NavigationControls(this._webViewController, {Key? key}) : super(key: key);
final WebViewController _webViewController;
Widget build(BuildContext context) {
return Row(
children: <Widget>[
IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: () async {
if (await _webViewController.canGoBack()) {
await _webViewController.goBack();
} else {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('No back history item')),
);
}
}
},
),
IconButton(
icon: const Icon(Icons.arrow_forward_ios),
onPressed: () async {
if (await _webViewController.canGoForward()) {
await _webViewController.goForward();
} else {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('No forward history item')),
);
}
}
},
),
IconButton(
icon: const Icon(Icons.replay),
onPressed: () => _webViewController.reload(),
),
],
);
}
}
4.4 执行 JavaScript
// 执行 JavaScript 代码
_controller.runJavaScript('alert("Hello from Flutter!");');
// 执行 JavaScript 代码并获取返回结果
final result = await _controller.runJavaScriptReturningResult(
'document.body.innerText.length'
);
debugPrint('Body text length: $result');
4.5 监听 JavaScript 消息
// 添加 JavaScript 通道
_controller.addJavaScriptChannel(
'Toaster',
onMessageReceived: (JavaScriptMessage message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message.message)),
);
},
);
// 在网页中发送消息到 Flutter
// window.Toaster.postMessage('Hello from JavaScript!');
4.6 加载不同类型的内容
// 加载网络资源
_controller.loadRequest(Uri.parse('https://flutter.dev'));
// 加载本地文件
_controller.loadFile('/path/to/local/file.html');
// 加载 Flutter 资源
_controller.loadFlutterAsset('assets/html/index.html');
// 加载 HTML 字符串
_controller.loadHtmlString('''
<html>
<body>
<h1>Hello, World!</h1>
<p>This is HTML content loaded from a string.</p>
</body>
</html>
''', baseUrl: Uri.parse('https://example.com'));
5. 注意事项
5.1 权限配置
确保正确配置网络权限,否则 WebView 将无法加载网络资源。同时,注意应用级别的设置,避免安装时出现权限错误。
5.2 鸿蒙平台兼容性
- 支持鸿蒙 API 12 及以上版本
- 要求 Flutter 版本:3.7.12-ohos-1.1.1 及以上
- 要求鸿蒙 SDK 版本:5.0.0(12) 及以上
5.3 性能优化
- 避免在 WebView 中加载过于复杂的网页内容
- 合理使用 JavaScript 通道,避免频繁的双向通信
- 在不需要时及时释放 WebView 资源
5.4 安全性考虑
- 谨慎处理来自网页的 JavaScript 消息
- 对加载的网页内容进行适当的安全验证
- 考虑使用内容安全策略 (CSP) 保护应用
6. 总结
webview_flutter 是一个功能强大的 Flutter 插件,为开发者提供了在 Flutter 应用中嵌入网页内容的能力。在鸿蒙平台上,该插件提供了与其他平台一致的功能体验,支持网络资源加载、JavaScript 执行、导航控制等核心功能。
使用该插件的关键步骤包括:
- 通过 git 形式引入自定义修改版本的依赖
- 配置网络权限和应用级别
- 创建 WebViewController 并配置导航委托
- 使用 WebViewWidget 在界面中显示 WebView
- 实现导航控制和 JavaScript 交互
webview_flutter 插件为鸿蒙平台上的 Flutter 应用提供了强大的网页嵌入能力,使开发者能够轻松构建混合内容应用,结合原生应用的性能优势和网页内容的灵活性。
无论是构建需要嵌入外部网页的应用,还是需要实现复杂网页交互的功能,webview_flutter 都是鸿蒙平台上 Flutter 开发者的理想选择。
更多推荐



所有评论(0)