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,有需要的可以下載下來查看學習。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM