Flutter桌面端开发——WebView
想要我们的应用打开网站,但是又不想跳转浏览器怎么办?诶,我们就可以使用这次介绍的这个插件。但这个插件还是有局限性,和微信电脑端一样,会新增一个窗口来浏览。若想在我们的应用页面中显示网页,可以使用webview_windows,但这个插件只能在windows端使用,所以就不介绍了。
desktop_webview_window
安装🛠
点击desktop_webview_window获取最新版本。以下是在编写本文章时的最新版本:
desktop_webview_window: ^0.1.6
如果你是在Linux上使用,还有运行以下命令:
sudo apt install webkit2gtk-4.0
🤖提示:使用该插件必须安装WebView2 Runtime。win11已自带,但是win10并不一定有(Edge更新了可能会安装好),所以你必须考虑向用户分发WebView2 Runtime,具体可以查看 https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution
使用🍜
WebViewWindow下一共有3个方法:
create
:创建一个WebView窗口clearAll
:关闭所有创建的WebView窗口isWebviewAvailable
:检查当前设备上是否有 WebView 运行时可用
在正式使用前,请在main.dart中添加如下代码:
void main() async {
// 必选在前面
if (runWebViewTitleBarWidget(args)) {
return;
}
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
isWebviewAvailable
如果用户没有安装WebView2 Runtime是无法使用该插件的,所以得先检测一下:
_available = await WebviewWindow.isWebviewAvailable();
create
该方法传入一个CreateConfiguration对象,该对象有以下几个属性:
int windowWidth
:WebView窗口的宽int windowHeight
:WebView窗口的高String title
:WebView窗口的标题int titleBarHeight
:WebView窗口的标题栏的高int titleBarTopPadding
:WebView窗口的标题栏的上内边距String userDataFolderWindows
:存储用户数据文件夹
final webView = await WebviewWindow.create();
webView.launch(https://www.acfun.cn);
还能保存播放的进度😲(演示前已打开过一遍)
前面几个参数看名字一目了然。我们来看看最后一个。
userDataFolderWindows需要传递一个本地路径,用来存储一些数据。
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
Future<String> _getDocument() async {
final document = await getApplicationDocumentsDirectory();
return path.join(document.path, 'flutter_desktop');
}
修改WebviewWindow.create方法:
final webView = await WebviewWindow.create(
configuration: CreateConfiguration(
title: 'AcFun',
userDataFolderWindows: await _getDocument(),
),
);
webView.launch(_url);
再次运行,打开我们设置好的路径,会出现如下文件夹:
里面全是一些我不认识的文件夹和文件😅。
使用WebviewWindow.create方法返回的WebView除了 launch 方法外,还有其他方法。
WebView
-
launch
:创建一个WebView窗口 -
back
:导航到历史记录中的上一页 -
forward
:导航到历史记录中的下一页 -
reload
:重新加载当前页面 -
stop
:停止所有导航和挂起的资源获取 -
close
:关闭 Web 视图窗口 -
onClose
:关闭Web窗口时的回调方法 -
isNavigating
:如果 webview 当前正在加载页面,则为 true -
setBrightness
:更改 webview 主题。仅适用于:macOS(Brightness.dark 仅 10.14+ -
setPromptHandler
:设置提示处理程序。仅macOS -
registerJavaScriptMessageHandler
:注册可以从 Javascript 代码调用的消息处理程序。仅macOS -
unregisterJavaScriptMessageHandler
:注销可以从 Javascript 代码调用的消息处理程序。仅macOS -
addScriptToExecuteOnDocumentCreated
:添加要在创建的文档上执行的脚本 -
setApplicationNameForUserAgent
:将字符串附加到 webview 的用户代理 -
setOnHistoryChangedCallback
:注册将在 webview 历史记录更改时调用的回调 -
addOnUrlRequestCallback
:添加 URL 请求回调 -
removeOnUrlRequestCallback
:删除 URL 请求回调 -
evaluateJavaScript
:计算javascript
前面几个容易的和仅在macOS端的就不演示了,因为不可抗拒原因,我们来看看后面几个:
addScriptToExecuteOnDocumentCreated
在launch方法前添加如下代码:
webView.addScriptToExecuteOnDocumentCreated('''
console.log("Hello Flutter")
''');
然后打开我们的网页,按F12调出开发工具(按了没反应可以先全屏再多按几次)
我们可以看到,这段代码被运行了2次🤔,修改成如下代码就行:
webView.addScriptToExecuteOnDocumentCreated('''
window.onload = function() {
console.log("Hello Flutter");
}
''');
setApplicationNameForUserAgent
webView.setApplicationNameForUserAgent('FlutterDesk');
setOnHistoryChangedCallback
检测当前页面是否可以使用左上角箭头前进后退一个页面。返回的是bool值
webView.setOnHistoryChangedCallback((canGoBack, canGoForward) {
print('canGoBack: $canGoBack');
print('canGoForward: $canGoForward');
});
addOnUrlRequestCallback
通过使用该方法我们可以获取一些回调信息。来模拟以下网页浏览记录:
List<String> _allUrl = [];
webView.addOnUrlRequestCallback((url) {
_allUrl.add(url);
setState(() {});
});
removeOnUrlRequestCallback
webView.removeOnUrlRequestCallback((url) {});
evaluateJavaScript
在页面进行 JavaScript 的运算
final _javaScriptToEval = [
"""
function test() {
return;
}
test();
""",
'eval({"name": "test", "user_agent": navigator.userAgent})',
'1 + 1',
'undefined',
'1.0 + 1.0',
'"test"',
];
webView.removeOnUrlRequestCallback((url) {});
for (final javaScript in _javaScriptToEval) {
try {
final ret = await webView.evaluateJavaScript(javaScript);
debugPrint('evaluateJavaScript: $ret');
} catch (e) {
debugPrint('evaluateJavaScript error: $e \n $javaScript');
}
}
onClose
当Web窗口被关闭时要做的事情
webView.onClose.whenComplete(() => BotToast.showText(text: 'Web窗口已关闭'));
clearAll
关闭打开的说有Web窗口
WebviewWindow.clearAll().whenComplete(() => BotToast.showText(text: '所有Web窗口已关闭'));
🛫OK,以上就是这篇文章的全部内容,仅针对插件的当前版本,并不能保证适用于以后插件用法的更新迭代。
最后,感谢boyan01对以上插件的开发和维护😁。本应用代码已上传至 github 和 gitee,有需要的可以下载下来查看学习。