注册

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

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


screen_capturer


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


安装🛠


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


screen_capturer: ^0.1.0

使用🥟


该插件的主体是 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自带的截图又有些差别,自带的只会将截图保存到剪切板中。


screen_text_extractor


安装🛠


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


screen_text_extractor: ^0.1.0

使用🥟


该插件的主体是 ScreenTextExtractor.instance ,其下有7个方法:



  1. isAccessAllowed:检测是否有进行相关操作的权限,仅macOS
  2. requestAccess:申请进行相关操作的权限,仅macOS
  3. extractFromClipboard:从剪切板提取内容
  4. extractFromScreenSelection:从选择的屏幕提取
  5. simulateCtrlCKeyPress:模拟 Ctrl + c ,返回一个布尔值

前面4个仅macOS使用的方法和screen_capturer一样,这里就不多赘述。后面3个方法将会返回一个 Future 的 ExtractedData 对象。


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


String _text = '获取的内容将会在这里🤪';

获取剪切板内容


ExtractedData data = await ScreenTextExtractor.instance.extractFromClipboard();
_text = data.text;
setState((){});

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


无标题


使用该方法看一下:


1


我们将会得到一个空白的内容。为了更好的用户体验,我们可以添加个条件。


if (data.text!.isEmpty) {
BotToast.showText(text: '剪切板什么都没有🤨');
} else {
_text = data.text!;
setState(() {});
}

我们现在复制一段内容:


无标题


然后看看效果:


2


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


1


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


3


直接为空了😶


获取选区内容


ExtractedData data = await ScreenTextExtractor.instance.extractFromScreenSelection(
useAccessibilityAPIFirst: false, // 使用辅助功能API,仅macOS
);
if (data.text!.isEmpty) {
BotToast.showText(text: '剪切板什么都没有🤨');
} else {
_text = data.text!;
setState(() {});
}

👻该方法如果是在windows端,返回的就是extractFromClipboard()方法的结果,在macOS端和Linux端暂时无法演示😪


pasteboard


安装🛠


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


pasteboard: ^0.0.2

使用🥟


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



  • image:复制图片
  • file:复制文件/文本
  • writeImage:粘贴图片
  • writeFile:粘贴文件/文本

复制粘贴文本


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


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

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


final TextEditingController _controller = TextEditingController();

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




  • 复制文本


    void _copyText() async {
    if (_controller.text.isEmpty) {
    BotToast.showText(text: '啥都没输入,你要我复制什么🥴');
    } else {
    final lines = const LineSplitter().convert(_controller.text);
    await Pasteboard.writeFiles(lines);
    }
    }



  • 粘贴文本


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



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


无标题


来看看效果:


1


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


2


通过测试可以知道,最终的结果是一个数组。我们再来看看剪切板有没有记录:


无标题


这里其实用的是上面同一张图,因为没有变化所以就没再截图了。


通过以上内容,我们可以发现,pasteboard 的复制粘贴是和系统隔开的。


复制粘贴文件


其实代码可以不用修改,但是为了更好的显示,我们还是修改以下:


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


图片本质上也是文件,可以直接使用上面的方法进行复制粘贴。所以关于图片的方法就不讲解了


(🤫ps: 其实是我使用官方例子的方法,用Base64图片进行测试,发现无法得到想要的结果。使用了官方的例子也是一样。复制图片的方法需要传递一个Uint8List参数,虽然可以使用其他方法转换,但是就变得麻烦了。以后我会出一篇关于用 CustomPaint 绘制图片的文章,里面会用到将图片转换成Uint8List对象的方法)。


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,有需要的可以下载下来查看学习。


作者:菠萝橙子丶
链接:https://juejin.cn/post/7076983397691686919
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册