拖動文件算是一個比較常見的功能,比如聊天、打開文件。現在我們通過第三方插件,在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 成員們對以上插件的開發和維護😁。
