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();

微信截图_20220321112959

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);

image

还能保存播放的进度😲(演示前已打开过一遍)

前面几个参数看名字一目了然。我们来看看最后一个。

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);

再次运行,打开我们设置好的路径,会出现如下文件夹:

微信截图_20220321115035

里面全是一些我不认识的文件夹和文件😅。

使用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调出开发工具(按了没反应可以先全屏再多按几次)

微信截图_20220321123505

我们可以看到,这段代码被运行了2次🤔,修改成如下代码就行:

webView.addScriptToExecuteOnDocumentCreated('''
  window.onload = function() {
    console.log("Hello Flutter");
  }
''');
setApplicationNameForUserAgent
webView.setApplicationNameForUserAgent('FlutterDesk');

微信截图_20220321125040

setOnHistoryChangedCallback

检测当前页面是否可以使用左上角箭头前进后退一个页面。返回的是bool值

webView.setOnHistoryChangedCallback((canGoBack, canGoForward) {
  print('canGoBack: $canGoBack');
  print('canGoForward: $canGoForward');
});
addOnUrlRequestCallback

通过使用该方法我们可以获取一些回调信息。来模拟以下网页浏览记录:

List<String> _allUrl = [];
webView.addOnUrlRequestCallback((url) {
  _allUrl.add(url);
  setState(() {});
});

image

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');
  }
}

微信截图_20220321160812

onClose

当Web窗口被关闭时要做的事情

webView.onClose.whenComplete(() => BotToast.showText(text: 'Web窗口已关闭'));

3

clearAll

关闭打开的说有Web窗口

WebviewWindow.clearAll().whenComplete(() => BotToast.showText(text: '所有Web窗口已关闭'));

4

🛫OK,以上就是这篇文章的全部内容,仅针对插件的当前版本,并不能保证适用于以后插件用法的更新迭代。

最后,感谢boyan01对以上插件的开发和维护😁。本应用代码已上传至 githubgitee,有需要的可以下载下来查看学习。

posted @ 2022-03-23 09:16  菠萝橙子丶  阅读(3831)  评论(1编辑  收藏  举报