flutter_native_drag_n_drop
一个 flutter 插件,用于支持原生拖放,特别是将文件(仅文件)拖出应用程序边界。
待办事项(未来版本)
- 更好的拖动图像处理(移除原生实现,拖动图像应在 dart 端设置)
- Windows 实现
用法
-
要使用此插件,请在 pubspec.yaml 文件中将 `flutter_native_drag_n_drop` 添加为依赖项。
-
使用 `NativeDraggable` 小部件,并传递 `NativeDragItem` 对象进行应用程序内的拖放,以及 `NativeDragFileItem` 对象以支持应用程序之间的拖放。不允许混合使用两者。当您在应用程序内放置对象时,您必须使用这些对象中的 `data` 对象。否则,您可以传递一个 `fileStreamCallback` 函数并返回一个流,该流会将二进制数据写入应用程序外部的一个文件中。
NativeDragItem 与 NativeDragFileItem
`NativeDragItem` 用于仅在应用程序内拖放(例如文件夹、图像)。
NativeDragItem<T extends Object>(
required String name,
T? data
)
`NativeDragFileItem` 用于文件,特别是当您希望支持在应用程序外部进行拖放时(例如将文件拖到 Finder 或 Mail 客户端)。
NativeDragFileItem<T extends Object> extends NativeDragItem(
required String fileName,
required int fileSize
)
NativeDraggable(
child: Container(),
// use items OR fileItems. Not both!
items: [NativeDragItem(name: "helloWorld.jpeg", data: helloWorldImg)],
fileItems: [NativeDragFileItem(fileName: "helloWorld.jpeg", fileSize: 1024, data: helloWorldImg)],
fileStreamCallback: (item, fileName, url, progressController) async* {
// item is the desired 'NativeDragFileItem' object, fileItem the name of the file, url the location where the user dropped the item, progressController an object where you have to pass the current progress of the fileStream in bytes. The system use the progress to update the progress indicator in Finder
// must return a Stream<Uint8List> object and must write file data into it
},
onDragStarted: (event) {
// callback when drag has started
},
onDragUpdate: (event) {
// callback when drag has moved
},
onDragEnd: (event) {
// callback when drag has ended
},
)
- 使用 `NativeDropTarget` 在应用程序内接收拖放事件。
NativeDropTarget(
builder: (context, candidateData, rejectedData) {
return Container();
},
onDragEntered: (details) {
// callback when drag has entered the drop area
},
onDragExited: (details) {
// callback when drag has exited the drop area
},
onDragUpdated: (details) {
// callback when drag has moved within the drop area
},
onDragDone: (details) {
// callback when drag has dropped
},
onWillAccept: (details) {
// returns a boolean if drag item should be accepted
}
)
示例
我们希望支持在应用程序内以及应用程序外部拖放图像文件。为此,我们创建了一个带有 `NativeDragFileItem` 对象的 `NativeDraggable` 小部件。
NativeDraggable(
child: Container(),
fileItems: [
NativeDragFileItem(
fileName: "image.jpg",
fileSize: image.size,
data: AssetImage("image.jpg"))
],
fileStreamCallback: passFileContent,
)
我们将 `passFileContent` 函数作为文件流回调传递。在此函数内部,我们将字节写入流并更新进度指示器。
Stream<Uint8List> passFileContent(
NativeDragItem<Object> item,
String fileName,
String url,
ProgressController progressController) async* {
final response = FileService.downloadFile(
name: "image.jpg",
onReceive: (count, total) {
progressController.updateProgress(count);
}
)
final byteStream = response.stream:
await for (final bytes in byteStream) {
yield Uint8List.fromList(bytes);
}
}
要在应用程序内接收文件,我们创建了一个 `NativeDropTarget` 对象,并从 `data` 变量读取图像。
NativeDropTarget(
builder: (context, candidateData, rejectedData) {
return Container();
},
onDragDone: (details) {
final image = details.items.first.data! as AssetImage;
},
onWillAccept: (details) {
return true;
}
)
