Flutter原生拖拽功能插件flutter_native_drag_n_drop的使用
Flutter原生拖拽功能插件 flutter_native_drag_n_drop
的使用
flutter_native_drag_n_drop
是一个支持原生拖放功能的Flutter插件,特别适用于将文件从应用程序外部拖放到应用内或反之。本文将详细介绍如何使用这个插件,并提供完整的示例代码。
插件特性
- 支持将文件从应用外部拖放到应用内部(例如从Finder或邮件客户端拖动文件到应用)。
- 支持在应用内部进行拖放操作。
- 目前仅支持macOS平台。
使用步骤
1. 添加依赖
首先,在您的 pubspec.yaml
文件中添加 flutter_native_drag_n_drop
作为依赖项:
dependencies:
flutter_native_drag_n_drop: ^0.1.0
2. 使用 NativeDraggable
和 NativeDropTarget
NativeDraggable
NativeDraggable
是用于实现拖拽功能的核心组件。您可以传递 NativeDragItem
对象来实现在应用内的拖放,或者传递 NativeDragFileItem
对象来支持跨应用的拖放。
NativeDraggable(
child: Container(), // 拖拽时显示的子组件
items: [NativeDragItem(name: "helloWorld.jpeg", data: helloWorldImg)], // 应用内拖拽项目
fileItems: [NativeDragFileItem(fileName: "helloWorld.jpeg", fileSize: 1024, data: helloWorldImg)], // 跨应用拖拽项目
fileStreamCallback: (item, fileName, url, progressController) async* {
// 实现文件流回调函数
},
onDragStarted: (event) {
// 拖拽开始时的回调
},
onDragUpdate: (event) {
// 拖拽过程中更新时的回调
},
onDragEnd: (event) {
// 拖拽结束时的回调
},
)
NativeDropTarget
NativeDropTarget
用于接收拖拽事件并处理拖拽内容。
NativeDropTarget(
builder: (context, candidateData, rejectedData) {
return Container(); // 接收拖拽内容时显示的组件
},
onDragEntered: (details) {
// 拖拽进入目标区域时的回调
},
onDragExited: (details) {
// 拖拽离开目标区域时的回调
},
onDragUpdated: (details) {
// 拖拽在目标区域内移动时的回调
},
onDragDone: (details) {
// 拖拽完成时的回调
},
onWillAccept: (details) {
// 判断是否接受拖拽项目
return true;
}
)
3. 示例代码
以下是一个完整的示例,演示了如何在应用内和应用外进行图片文件的拖放操作:
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_native_drag_n_drop/flutter_native_drag_n_drop.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _dragging = false;
AssetImage? _img;
ByteData? _imageData;
[@override](/user/override)
void initState() {
super.initState();
// 加载图片数据
rootBundle.load("assets/maldives.jpg").then((imgData) {
setState(() {
_imageData = imgData;
});
});
// 监听拖拽事件
FlutterNativeDragNDrop.instance.addDragEventListener(onDragEvent);
}
bool isDragging = false;
void onDragEvent(DragEvent e) {
if (e is DragBeginEvent) {
setState(() {
isDragging = true;
});
return;
}
if (e is DragEndedEvent) {
setState(() {
isDragging = false;
});
return;
}
}
[@override](/user/override)
void dispose() {
FlutterNativeDragNDrop.instance.removeDragEventListener(onDragEvent);
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: isDragging ? const Text('Its dragging time') : const Text('Native drag & drop example'),
),
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
NativeDropTarget(
builder: ((context, candidateData, rejectedData) {
return Container(
height: 200,
width: 200,
color: _dragging ? Colors.blueAccent : Colors.grey,
child: _img != null
? Image(height: 200, width: 200, image: _img!)
: const Center(child: Text("Drop Target")),
);
}),
onDragEntered: (details) {
setState(() {
_dragging = true;
});
},
onDragExited: (details) {
setState(() {
_dragging = false;
});
},
onDragDone: (details) {
AssetImage droppedImage = details.items.first.data! as AssetImage;
setState(() {
_dragging = false;
_img = droppedImage;
});
},
onWillAccept: (details) {
return true;
},
),
const SizedBox(width: 15),
NativeDraggable(
child: const Image(height: 200, width: 200, image: AssetImage("assets/maldives.jpg")),
fileStreamCallback: passFileContent,
fileItems: [
NativeDragFileItem(
fileName: "maldives.jpeg",
fileSize: _imageData != null ? _imageData!.lengthInBytes : 0,
data: const AssetImage("assets/maldives.jpg"))
],
)
],
))));
}
Stream<Uint8List> passFileContent(
NativeDragItem<Object> item, String fileName, String url, ProgressController progressController) async* {
final buffer = _imageData!.buffer.asUint8List();
final range = buffer.length ~/ 10;
for (var i = 0; i < 10; i++) {
final startByte = i * range;
final endByte = startByte + range;
final sub = buffer.sublist(startByte, endByte);
yield sub;
progressController.updateProgress(endByte);
await Future.delayed(const Duration(milliseconds: 500));
}
return;
}
}
更多关于Flutter原生拖拽功能插件flutter_native_drag_n_drop的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复