You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 18:32:51