Flutter Desktop如何监听剪贴板内容变化?
Flutter桌面端剪贴板实时监听方案
方案一:定时轮询(快速实现)
Flutter官方services库未提供剪贴板变化的监听API,最简单的替代方式是定时轮询剪贴板内容,与上一次记录的内容对比,发现差异时触发自定义逻辑。
示例代码:
import 'package:flutter/services.dart'; import 'dart:async'; class ClipboardMonitor { String _lastContent = ''; Timer? _timer; void startMonitoring({Duration interval = const Duration(milliseconds: 500)}) { _timer?.cancel(); _timer = Timer.periodic(interval, (timer) async { final data = await Clipboard.getData(Clipboard.kTextPlain); final currentContent = data?.text ?? ''; if (currentContent != _lastContent) { _lastContent = currentContent; // 剪贴板内容变化,触发你的逻辑 _onClipboardChanged(currentContent); } }); } void _onClipboardChanged(String content) { print('剪贴板内容更新:$content'); // 这里添加你的业务处理代码 } void stopMonitoring() { _timer?.cancel(); } } // 使用示例 // final monitor = ClipboardMonitor(); // monitor.startMonitoring(); // 不再需要时调用 monitor.stopMonitoring();
方案二:平台原生实现(高效实时)
如果需要更高效的实时监听,需针对不同桌面平台编写原生代码,通过MethodChannel将剪贴板变化事件传递给Flutter。
Windows平台
使用Win32 API的AddClipboardFormatListener注册剪贴板监听,当剪贴板内容变化时,通过MethodChannel通知Flutter。
核心原生逻辑(C++):
// 注册剪贴板监听 AddClipboardFormatListener(hwnd); // 处理WM_CLIPBOARDUPDATE消息 LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CLIPBOARDUPDATE: // 获取剪贴板文本并通过MethodChannel发送给Flutter SendClipboardTextToFlutter(); break; // 其他消息处理... } return DefWindowProc(hwnd, uMsg, wParam, lParam); }
macOS平台
利用NSPasteboard的changeCount属性或添加观察者监听变化:
核心原生逻辑(Objective-C):
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; [pasteboard addObserver:self forKeyPath:@"changeCount" options:NSKeyValueObservingOptionNew context:nil]; // 观察者回调 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context { if ([keyPath isEqualToString:@"changeCount"]) { NSString *clipboardText = [pasteboard stringForType:NSPasteboardTypeString]; // 通过MethodChannel发送给Flutter [self.channel invokeMethod:@"clipboardChanged" arguments:clipboardText]; } }
Linux平台
使用GTK的GtkClipboard监听owner-change信号:
核心原生逻辑(C):
GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); g_signal_connect(clipboard, "owner-change", G_CALLBACK(on_clipboard_change), NULL); // 回调函数 void on_clipboard_change(GtkClipboard *clipboard, GdkEventOwnerChange *event, gpointer user_data) { gchar *text = gtk_clipboard_wait_for_text(clipboard); if (text) { // 通过MethodChannel发送给Flutter send_to_flutter(text); g_free(text); } }
Flutter端MethodChannel调用示例
import 'package:flutter/services.dart'; class NativeClipboardMonitor { static const MethodChannel _channel = MethodChannel('clipboard_monitor'); static void startMonitoring(Function(String content) onChanged) { _channel.setMethodCallHandler((call) async { if (call.method == 'clipboardChanged') { final content = call.arguments as String; onChanged(content); } }); _channel.invokeMethod('startMonitoring'); } static void stopMonitoring() { _channel.invokeMethod('stopMonitoring'); } } // 使用示例 // NativeClipboardMonitor.startMonitoring((content) { // print('剪贴板更新:$content'); // });
内容的提问来源于stack exchange,提问作者Kartik
相关产品推荐
相关产品推荐

