Flutter桌面端开发——复制和粘贴内容

注意:查看本文章前请先查看更新日志,以至于该文章适合插件的最新版本

更新日志
详情日期
更新了插件的版本号2023-08-13
更新了pasteboard在0.1.0版本的用法2022-05-30
更新了screen_text_extractor在0.1.1版本的用法2022-05-10

复制和粘贴这个功能,一般系统都自带,简单的按几个键就能完成。但是有时候我们想要自己在应用中集成这个功能,或者想在用户复制文字后不使用粘贴操作,就让复制的内容直接出现在我们的应用中。想要实现该功能,就可以用我今天介绍的几个插件。

screen_capturer

这个方法是用来截取屏幕的。本来想写一期介绍截屏插件的,但是找了一圈只找到这个适用于桌面端,只写这一个插件篇幅又太短,所以直接加了进来。

安装🛠

点击screen_capturer获取最新版本。以下是在编写本文章时的最新版本:

screen_capturer: ^0.1.6

使用🥟

该插件的主体是 ScreenCapturer.instance ,其下有3个方法:isAccessAllowed 、requestAccess 和 capture。

isAccessAllowed 和 requestAccess仅在 macOS中适用,分别用来检测和申请截图的权限。

await ScreenCapturer.instance.requestAccess();  // 申请权限
bool _isAllowed = await ScreenCapturer.instance.isAccessAllowed ();  // 检测是否拥有权限

我们截图的目的是把图片显示出来,所以在正式截图前先定义个图片路径的参数:

String _image;

接下来介绍截图的主要方法 capture,该方法可以传递2个参数:

  • String? imagePath:该属性为必填,传递一个图片保存的路径和名称
  • bool silent:设置是否开启截屏的提示音
String _imageName = '${DateTime.now().millisecondsSinceEpoch}.png';  // 设置图片名称
String _imagePath = 'C:\\Users\\ilgnefz\\Pictures\\$_imageName';  // 设置图片保存的路径
CapturedData? _capturedData = await ScreenCapturer.instance.capture(imagePath: _imagePath);
if (_capturedData != null) {
  _image = _capturedData.imagePath;
  setState(() {});
} else {
  BotToast.showText(text: '截图被取消了');
}

1

通过运行可以发现,这里调用的其实是系统的截图功能,然后将截取的图片进行了保存。和windows自带的截图又有些差别,自带的只会将截图保存到剪切板中。

新版的添加了readImageFromClipboard方法用来读取剪切板的图片,该方法返回一个 Uint8List 类型的数据,关于将Uint8List转换为可显示的图片请参考Flutter学习:使用CustomPaint绘制图片

screen_text_extractor

安装🛠

点击screen_text_extractor获取最新版本。以下是在编写本文章时的最新版本:

screen_text_extractor: ^0.1.3

使用🥟

在使用前先实例化该对象

final screenTextExtractor = ScreenTextExtractor.instance;

实例化后的对象有以下3个方法:

  1. extract:主要获取剪切板内容的方法
  2. isAccessAllowed:检测是否有进行相关操作的权限,仅macOS
  3. requestAccess:申请进行相关操作的权限,仅macOS

后面2个仅macOS使用的方法和screen_capturer一样,这里就不多赘述。

我们先定义一个String对象用来显示获取到的内容:

String? _text;
void _getClipboardText() async {
  ExtractedData? data = await screenTextExtractor.extract(mode: ExtractMode.clipboard);
  _setText(data);
}

注意:mode 一共有两个值,分别是 ExtractMode.clipboard 和 ExtractMode.screenSelection(不建议使用,flutter会报错)

接下来我们让获取的内容显示出来

void _setText(ExtractedData? data) {
  if (data == null) {
    BotToast.showText(text: '剪切板什么都没有🤨');
  } else {
    if (_text == data.text) {
      BotToast.showText(text: '换个内容再粘贴吧🥱');
    } else {
      _text = data.text;
      _type = ClipboardType.text;
      setState(() {});
    }
  }
}

我们先在 windows 中按 windows键 + v 来调出剪切板,清空

image

然后来粘贴一下

image

我们现在复制一段内容:

image

然后看看效果:

image

获取成功😀,但是剪切板除了能存储文本,还是能存储图片的。

image

但是ExtractedData只有个text属性,我们来看下会发生什么:

image

直接为空了😶

pasteboard

安装🛠

点击pasteboard获取最新版本。以下是在编写本文章时的最新版本:

pasteboard: ^0.1.0

使用🥟

该插件中的 Pasteboard 对象一共拥有4个方法:

  • image:复制图片。仅iOS
  • writeImage:粘贴图片。仅iOS
  • text:复制文本
  • writeText:粘贴文本
  • file:复制文件(也可以复制文本)
  • writeFile:粘贴文件(也可以粘贴文本)

复制粘贴文本

当然,第一步先定义一个用来存储结果的变量:

String _text = '还没粘贴任何内容';

定义一个文本控制器,用来获取输入的内容:

final TextEditingController _controller = TextEditingController();

接下来使用 pasteboard 来实现复制和粘贴的功能:

  • 复制文本

    void _copyText() async {
      if (_controller.text.isEmpty) {
        BotToast.showText(text: '啥都没输入,你要我复制什么🥴');
      } else {
        Pasteboard.writeText(_controller.text);
      }
    }
    
  • 粘贴文本

    void _pastText() async {
      String? results = await Pasteboard.text;
      _text = results ?? '';
      setState(() {});
    }
    

我们先来试一下,不用复制直接直接粘贴会发生什么。此时我的剪切板有一条内容:

image

我们可以发现,它可以直接读取我们剪切板刚复制的内容。试下复制再粘贴:

image

成功。我们再来看看剪切板有没有记录:

image

通过以上可得,writeText方法会将复制的文本内容存储到系统粘贴板上。

复制粘贴文件

writeFilewriteText一样,都是复制String类型,虽然名称叫writeFile,但是在我们自己开发的软件中一般用不到,所以复制文件我们直接使用系统的就行。

以下是粘贴文件的代码:

void _pastText() async {
  final results = await Pasteboard.files();
  if (results.isNotEmpty) {
    _text = '';
    for (final result in results) {
      _text += '$result\n';
    }
    setState(() {});
  } else {
    BotToast.showText(text: '我什么都不能给你,因为我也咩有😭');
  }
}

在这里,我使用了 url_launcher 插件,用来打开系统的文件浏览器。代码如下:

void _openExplorer() async {
  const _filePath = r'C:\Users\ilgnefz\Pictures';
  final Uri _uri = Uri.file(_filePath);
  await launch(_uri.toString());
}

来看看效果:

image

clipboard

安装🛠

点击clipboard获取最新版本。以下是在编写本文章时的最新版本:

clipboard: ^0.1.3

使用🥟

该插件拥有4个方法:

  • controlC:模仿 cttr + c 键,复制
  • controlC:模仿 cttr + v 键,粘贴
  • copy:复制
  • paste:粘贴

先来看看前面两个方法:

void _useCtrC() async {
  if (_controller.text.isEmpty) {
    BotToast.showText(text: '啥都没输入,你要我复制什么🥴');
  } else {
    await FlutterClipboard.controlC(_controller.text);
  }
}

void _useCtrV() async {
  ClipboardData result = await FlutterClipboard.controlV();
  _text = result.text.toString();
  setState(() {});
}

使用 controlV 会返回一个 ClipboardData 对象。

4

后面两个方法和前面的唯一不同,就是返回的是一个 String 对象:

void _useCopy() async {
  if (_controller.text.isEmpty) {
    BotToast.showText(text: '啥都没输入,你要我复制什么🥴');
  } else {
    await FlutterClipboard.copy(_controller.text);
  }
}

void _usePaste() async {
  _text = await FlutterClipboard.paste();
  setState(() {});
}

5

我们打开系统的剪切板可以发现,以上复制的内容都会被记录。我们试一下不按复制看能不能直接读取剪切板的信息进行粘贴:

6

试试 paste 方法:

7

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

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

posted @ 2022-03-19 16:08  菠萝橙子丶  阅读(2330)  评论(0编辑  收藏  举报