文章目录
- 添加网络权限:在 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”: “使用网络访问网页内容” } ] }
- 由于 WebView 可能需要系统级权限,需要将应用级别设置为 system_basic,否则在安装 HAP 包时可能会报错。具体配置方法请参考华为官方文档。
- 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); @override State<WebViewExample> createState() => _WebViewExampleState(); } class _WebViewExampleState extends State<WebViewExample> { late final WebViewController _controller; @override 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(‘nn====nError: $errorn====nn’); }, 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 } // … }
- WebViewWidget 用于在 Flutter 界面中显示 WebView 内容,需要传入之前创建的 WebViewController。 @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text(‘Flutter WebView 示例’), // 添加导航控制按钮 actions: [ NavigationControls(_controller), ], ), body: WebViewWidget(controller: _controller), // 显示 WebView ); }
- class NavigationControls extends StatelessWidget { const NavigationControls(this._webViewController, {Key? key}) : super(key: key); final WebViewController _webViewController; @override 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(), ), ], ); } }
- // 执行 JavaScript 代码 _controller.runJavaScript(‘alert(“Hello from Flutter!”);’); // 执行 JavaScript 代码并获取返回结果 final result = await _controller.runJavaScriptReturningResult( ‘document.body.innerText.length’ ); debugPrint(‘Body text length: $result’);
- // 添加 JavaScript 通道 _controller.addJavaScriptChannel( ‘Toaster’, onMessageReceived: (JavaScriptMessage message) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(message.message)), ); }, ); // 在网页中发送消息到 Flutter // window.Toaster.postMessage(‘Hello from JavaScript!’);
- // 加载网络资源 _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’));
目录
- 1. 插件介绍
- 核心功能
- 鸿蒙平台支持
- 2. 依赖引入
- 配置步骤
- 3. 鸿蒙平台特殊配置
- 3.1 权限配置
- 3.2 应用级别配置
- 4. API 调用与使用示例
- 4.1 创建 WebViewController
- 4.2 创建 WebViewWidget
- 4.3 实现导航控制
- 4.4 执行 JavaScript
- 4.5 监听 JavaScript 消息
- 4.6 加载不同类型的内容
- 5. 注意事项
- 5.1 权限配置
- 5.2 鸿蒙平台兼容性
- 5.3 性能优化
- 5.4 安全性考虑
- 6. 总结
webview_flutter 是一个功能强大的 Flutter 插件,提供了 WebView 小部件,允许开发者在 Flutter 应用中嵌入网页内容。该插件支持多种平台,包括 iOS、Android、Web 和鸿蒙(API 12+)。
- 在 Flutter 应用中无缝嵌入网页内容
- 支持网络资源、本地文件和 Flutter 资源加载
- 提供完整的网页导航控制(前进、后退、刷新)
- 支持 JavaScript 执行和双向通信
- 提供网页加载进度监听和导航决策控制
- 支持自定义用户代理、背景颜色和缩放控制
在鸿蒙平台上,webview_flutter 插件基于鸿蒙的 WebView API(API 12+)实现,提供与其他平台一致的功能体验。支持鸿蒙 API 12 及以上版本。
由于这是一个针对鸿蒙平台的自定义修改版本,需要通过 git 形式引入依赖。
- 在项目的
pubspec.yaml 文件中,添加以下依赖配置:
dependencies:
webview_flutter:
git:
url: "https://gitcode.com/openharmony-tpc/flutter_packages.git"
path: "packages/webview_flutter"
- 执行以下命令获取依赖:
flutter pub get
pubspec.yaml 文件中,添加以下依赖配置:
- 添加网络权限:在
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": "使用网络访问网页内容"
}
]
}
entry/src/main/module.json5 文件中添加网络权限声明:entry/src/main/resources/base/element/string.json 文件中添加权限描述:
由于 WebView 可能需要系统级权限,需要将应用级别设置为 system_basic,否则在安装 HAP 包时可能会报错。具体配置方法请参考华为官方文档。
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);
@override
State<WebViewExample> createState() => _WebViewExampleState();
}
class _WebViewExampleState extends State<WebViewExample> {
late final WebViewController _controller;
@override
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('nn====nError: $errorn====nn');
},
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
}
// ...
}
WebViewWidget 用于在 Flutter 界面中显示 WebView 内容,需要传入之前创建的 WebViewController。
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter WebView 示例'),
// 添加导航控制按钮
actions: [
NavigationControls(_controller),
],
),
body: WebViewWidget(controller: _controller), // 显示 WebView
);
}
class NavigationControls extends StatelessWidget {
const NavigationControls(this._webViewController, {Key? key}) : super(key: key);
final WebViewController _webViewController;
@override
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(),
),
],
);
}
}
// 执行 JavaScript 代码
_controller.runJavaScript('alert("Hello from Flutter!");');
// 执行 JavaScript 代码并获取返回结果
final result = await _controller.runJavaScriptReturningResult(
'document.body.innerText.length'
);
debugPrint('Body text length: $result');
// 添加 JavaScript 通道
_controller.addJavaScriptChannel(
'Toaster',
onMessageReceived: (JavaScriptMessage message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message.message)),
);
},
);
// 在网页中发送消息到 Flutter
// window.Toaster.postMessage('Hello from JavaScript!');
// 加载网络资源
_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'));
确保正确配置网络权限,否则 WebView 将无法加载网络资源。同时,注意应用级别的设置,避免安装时出现权限错误。
- 支持鸿蒙 API 12 及以上版本
- 要求 Flutter 版本:3.7.12-ohos-1.1.1 及以上
- 要求鸿蒙 SDK 版本:5.0.0(12) 及以上
- 避免在 WebView 中加载过于复杂的网页内容
- 合理使用 JavaScript 通道,避免频繁的双向通信
- 在不需要时及时释放 WebView 资源
- 谨慎处理来自网页的 JavaScript 消息
- 对加载的网页内容进行适当的安全验证
- 考虑使用内容安全策略 (CSP) 保护应用
webview_flutter 是一个功能强大的 Flutter 插件,为开发者提供了在 Flutter 应用中嵌入网页内容的能力。在鸿蒙平台上,该插件提供了与其他平台一致的功能体验,支持网络资源加载、JavaScript 执行、导航控制等核心功能。
使用该插件的关键步骤包括:
- 通过 git 形式引入自定义修改版本的依赖
- 配置网络权限和应用级别
- 创建 WebViewController 并配置导航委托
- 使用 WebViewWidget 在界面中显示 WebView
- 实现导航控制和 JavaScript 交互
webview_flutter 插件为鸿蒙平台上的 Flutter 应用提供了强大的网页嵌入能力,使开发者能够轻松构建混合内容应用,结合原生应用的性能优势和网页内容的灵活性。
无论是构建需要嵌入外部网页的应用,还是需要实现复杂网页交互的功能,webview_flutter 都是鸿蒙平台上 Flutter 开发者的理想选择。
到此这篇关于在鸿蒙上使用webview_flutter包的文章就介绍到这了,更多相关鸿蒙使用webview_flutter包内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!
您可能感兴趣的文章:
- js 交互在Flutter 中使用 webview_flutter