Flutter桌面端开发——拖动文件到应用
拖动文件算是一个比较常见的功能,比如聊天、打开文件。现在我们通过第三方插件,在Flutter中实现一个从电脑磁盘拖动文件到我们的应用中,然后读取的功能。当然,这里只演示最简单的读取图片的功能。
desktop_drop
安装🛠
点击desktop_drop获取最新版本。以下是在编写本文章时的最新版本:
desktop_drop: ^0.3.3
认识DropTarget 🧩
desktop_drop 可以一次读取拖动的多个文件,最后获取的是以 XFile 对象存储的列表。我们要想直接使用 XFile 对象,还需要安装一个第三方的插件cross_file
,点这里获取。当然,我们也可以不使用该插件,因为对于我们来说,真正需要的只是文件的路径。可以通过以下方法获取:
final List<File> files = [];
// 这里用 XFiles 演示代替获取到的列表
XFiles.map((e) => files.add(File(e.path)));
不过我已经安装好了corss_file
,所以以下的内容都是使用该插件。
要想实现拖动文件读取功能,用到的就是 DropTarget 组件。让我们来看一下它都有哪些属性:
Key? key
:组件的唯一标识required Widget child
:子组件void Function(DropEventDetails)? onDragEntered
:拖动进入时void Function(DropEventDetails)? onDragExited
:拖动离开时void Function(DropDoneDetails)? onDragDone
:拖动完成后void Function(DropEventDetails)? onDragUpdated
:拖动移动位置时bool enable = true
:是否启用
知道了 DropTarget 的各项属性,我们接下来就来使用它吧。
使用🍖
我们的需求是拖动一张图片到应用程序,然后显示出来。所以,我们有两个不同的界面要显示。
先来做让用户拖动图片进应用的界面:
Widget uploadImage() {
return Center(
child: Container(
width: 400,
height: 200,
// 虚线框使用的是一个第三方插件dotted_decoration
decoration: DottedDecoration(
color: Colors.blue,
shape: Shape.box,
borderRadius: const BorderRadius.all(Radius.circular(24)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Icon(Icons.image, size: 60, color: Colors.blue),
SizedBox(height: 8),
Text(
'拖动图片打开',
style: TextStyle(fontSize: 24, color: Colors.blue),
),
],
),
),
);
}
现在还需要一个显示图片的页面。要想显示图片,需要传入一个文件对象:
Widget viewImage(XFile file) {
return Padding(
padding: const EdgeInsets.all(12.0),
child: Center(
child: DecoratedBox(
decoration: const BoxDecoration(
boxShadow: [
BoxShadow(blurRadius: 8, color: Colors.black26),
],
),
child: Image.file(
File(file.path),
),
),
),
);
}
好了,现在需要的就是编写用户拖动文件的方法了。
我们需要先定义一个对象用来存储获取到的图片路径(😁这里偷个懒,根据上面编写的代码,我们只显示一张图)。
定义一个 XFile 对象:
XFile? files;
定义一个拖入完成的方法:
void _dragDone(DropDoneDetails detail) {
setState(() {
file = detail.files.last; // 每次拖入文件都显示新的
});
}
使用以上内容:
@override
Widget build(BuildContext context) {
return DropTarget(
onDragDone: _dragDone,
child: file == null ? uploadImage() : viewImage(file!),
);
成功😀。
但是,好像有点小残缺。图片放进来显示后多了很多的噪点,变得不清晰了🤔难搞哦(经过多次测试,这应该是Flutter的一个bug,已经向 Flutter 提交了 issue)。
🛫OK,以上就是这篇文章的全部内容,仅针对插件的当前版本,并不能保证适用于以后插件用法的更新迭代。
最后,感谢 MixinNetwork 成员们对以上插件的开发和维护😁。