Flutter桌面端开发——拖动文件到应用

5,349 阅读3分钟

拖动文件算是一个比较常见的功能,比如聊天、打开文件。现在我们通过第三方插件,在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),
          ),
        ],
      ),
    ),
  );
}

微信截图_20220315111757

现在还需要一个显示图片的页面。要想显示图片,需要传入一个文件对象:

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!),
  );

image

成功😀。

但是,好像有点小残缺。图片放进来显示后多了很多的噪点,变得不清晰了🤔难搞哦(经过多次测试,这应该是Flutter的一个bug,已经向 Flutter 提交了 issue)。

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

最后,感谢 MixinNetwork 成员们对以上插件的开发和维护😁。本程序相关代码已上传至 githubgitee,有需要的可以下载下来查看学习。