Skip to content

Commit 1d28a55

Browse files
committed
Updated example and read me
1 parent ae51e84 commit 1d28a55

File tree

2 files changed

+130
-42
lines changed

2 files changed

+130
-42
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
</p>
1717

1818
A package that allows you to add native drag and drop support into your flutter app.
19+
1920
![iPadDropExample](https://user-images.githubusercontent.com/15949910/150702838-817e24cd-9494-43e3-a077-64a036393b0a.gif)
2021

2122
![dragndropex2](https://user-images.githubusercontent.com/15949910/150670673-c19d7d65-f9b0-4a3f-8e2a-aae8b241e28d.gif)
@@ -40,6 +41,7 @@ Widget build(BuildContext context) {
4041
allowedTotal: 5,
4142
allowedDropDataTypes: const [DropDataType.text, DropDataType.image, DropDataType.video],
4243
allowedDropFileExtensions: ['apk', 'dart'],
44+
receiveNonAllowedItems: false,
4345
child: receivedData.isNotEmpty
4446
? ListView.builder(
4547
itemCount: receivedData.length,
@@ -85,8 +87,9 @@ class DropData {
8587
```
8688
It is safe to assume that if the dataType is text or url then the dropText will be non null.
8789

88-
As for image, video, audio, pdf it is safe to assume the dropFile will be non null
90+
As for image, video, audio, pdf, file it is safe to assume the dropFile will be non null
8991

92+
All files are saved to the temp directory on the device so if you want to save the file to the device [copy its data to a file in the documents directory](https://programmingwithswift.com/how-to-save-a-file-locally-with-flutter/).
9093
## Todo
9194

9295
- [x] specify the number of items allowed to be dropped at a time

example/lib/src/home_view.dart

Lines changed: 126 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'dart:math';
12
import 'package:flutter/material.dart';
23
import 'package:native_drag_n_drop/native_drag_n_drop.dart';
34
import 'package:native_drag_n_drop_example/src/dropped_image_list_title.dart';
@@ -29,9 +30,8 @@ class _HomeViewState extends State<HomeView> {
2930
DropDataType.audio: true,
3031
DropDataType.file: true
3132
};
32-
33+
bool _receiveNonAllowedItems = true;
3334
List<String> allowedFileExtensions = [];
34-
var panelActiveStatus = [false, false, false];
3535
late StateSetter _setState;
3636
@override
3737
Widget build(BuildContext context) {
@@ -101,6 +101,48 @@ class _HomeViewState extends State<HomeView> {
101101
},
102102
),
103103
const Divider(),
104+
Padding(
105+
padding: const EdgeInsets.all(8.0),
106+
child: CheckboxListTile(
107+
title: const Text(
108+
"Receive non-allowed items if at least one item is allowed"),
109+
value: _receiveNonAllowedItems,
110+
subtitle: Row(
111+
children: [
112+
TextButton.icon(
113+
onPressed: () {
114+
showDialog(
115+
context: context,
116+
builder: (context) {
117+
return AlertDialog(
118+
content: const Text(
119+
"It is recommended to keep this enabled, and instead give feedback to the user when they have dropped an item that is not allowed."),
120+
actions: [
121+
TextButton(
122+
onPressed: () {
123+
Navigator.of(
124+
context)
125+
.pop();
126+
},
127+
child: const Text(
128+
"Awesome!"))
129+
],
130+
);
131+
});
132+
},
133+
icon: const Icon(Icons.info),
134+
label: const Text(
135+
"Why would I want this?")),
136+
const Spacer()
137+
],
138+
),
139+
onChanged: (bool? value) {
140+
_setState(() {
141+
_receiveNonAllowedItems = value!;
142+
});
143+
}),
144+
),
145+
const Divider(),
104146
const Center(child: Text('Allowed data types:')),
105147
...dataTypes.keys.map((key) {
106148
return CheckboxListTile(
@@ -113,29 +155,40 @@ class _HomeViewState extends State<HomeView> {
113155
});
114156
}).toList(),
115157
const Divider(),
116-
const Padding(
117-
padding: EdgeInsets.all(8.0),
158+
Padding(
159+
padding: const EdgeInsets.all(8.0),
118160
child: Center(
119-
child: Text('Allowed file extensions:')),
161+
child: Row(
162+
children: [
163+
const Text('Allowed file extensions:'),
164+
const Spacer(),
165+
ElevatedButton(
166+
onPressed: () {
167+
_displayTextInputDialog(context);
168+
},
169+
child: const Text("Add extension")),
170+
],
171+
)),
120172
),
121-
ElevatedButton(
122-
onPressed: () {
123-
_displayTextInputDialog(context);
124-
},
125-
child: const Text("Add extension")),
126173
...allowedFileExtensions.mapIndexed((ext, index) {
127-
return ListTile(
128-
title: Text(
129-
ext,
130-
),
131-
trailing: IconButton(
132-
icon: const Icon(Icons.close),
133-
onPressed: () {
134-
_setState(() {
135-
allowedFileExtensions.removeAt(index);
136-
});
137-
},
138-
),
174+
return Column(
175+
children: [
176+
ListTile(
177+
title: Text(
178+
ext,
179+
),
180+
trailing: IconButton(
181+
icon: const Icon(Icons.close),
182+
onPressed: () {
183+
_setState(() {
184+
allowedFileExtensions
185+
.removeAt(index);
186+
});
187+
},
188+
),
189+
),
190+
const Divider()
191+
],
139192
);
140193
}).toList(),
141194
],
@@ -151,7 +204,8 @@ class _HomeViewState extends State<HomeView> {
151204
allowedDropDataTypes: dataTypes.keys
152205
.where((element) => dataTypes[element] == true)
153206
.toList(),
154-
allowedDropFileExtensions: allowedFileExtensions);
207+
allowedDropFileExtensions: allowedFileExtensions,
208+
receiveNonAllowedItems: _receiveNonAllowedItems);
155209
}
156210
},
157211
),
@@ -167,6 +221,7 @@ class _HomeViewState extends State<HomeView> {
167221
.where((element) => dataTypes[element] == true)
168222
.toList(),
169223
allowedFileExtensions: allowedFileExtensions,
224+
receiveNonAllowedItems: _receiveNonAllowedItems,
170225
created: (DropViewController controller) {
171226
_dropViewController = controller;
172227
},
@@ -232,12 +287,14 @@ class ListNativeDropView extends StatefulWidget {
232287
final List<DropDataType>? allowedDataTypes;
233288
final List<String>? allowedFileExtensions;
234289
final DropViewCreatedCallback created;
290+
final bool receiveNonAllowedItems;
235291
const ListNativeDropView(
236292
{Key? key,
237293
required this.allowedItemsAtOnce,
238294
this.allowedDataTypes,
239295
this.allowedFileExtensions,
240-
required this.created})
296+
required this.created,
297+
this.receiveNonAllowedItems = false})
241298
: super(key: key);
242299

243300
@override
@@ -274,30 +331,58 @@ class _ListNativeDropViewState extends State<ListNativeDropView> {
274331
allowedTotal: widget.allowedItemsAtOnce,
275332
allowedDropDataTypes: widget.allowedDataTypes,
276333
allowedDropFileExtensions: widget.allowedFileExtensions,
277-
receiveNonAllowedItems: false,
334+
receiveNonAllowedItems: widget.receiveNonAllowedItems,
278335
created: widget.created,
279336
child: receivedData.isNotEmpty
280337
? ListView.builder(
281338
shrinkWrap: true,
282339
itemCount: receivedData.length,
283340
itemBuilder: (context, index) {
284-
var data = receivedData[index];
285-
if (data.type == DropDataType.text) {
286-
return ListTile(
287-
title: Text(data.dropText!),
288-
subtitle: Text(data.type.toString()),
289-
);
290-
}
291-
if (data.type == DropDataType.image) {
292-
return DroppedImageListTile(
293-
dropData: data,
294-
);
295-
}
341+
return Dismissible(
342+
direction: DismissDirection.endToStart,
343+
onDismissed: (d) {
344+
receivedData.removeAt(index);
345+
setState(() {});
346+
},
347+
background: Container(
348+
color: Colors.red,
349+
child: Row(
350+
mainAxisAlignment: MainAxisAlignment.center,
351+
children: const [
352+
Spacer(),
353+
Icon(
354+
Icons.delete,
355+
color: Colors.white,
356+
size: 30,
357+
),
358+
SizedBox(
359+
width: 10,
360+
)
361+
],
362+
),
363+
),
364+
key: Key(Random().nextInt(10000).toString()),
365+
child: Builder(
366+
builder: (context) {
367+
var data = receivedData[index];
368+
if (data.type == DropDataType.text) {
369+
return ListTile(
370+
title: Text(data.dropText!),
371+
subtitle: Text(data.type.toString()),
372+
);
373+
}
374+
if (data.type == DropDataType.image) {
375+
return DroppedImageListTile(
376+
dropData: data,
377+
);
378+
}
296379

297-
return ListTile(
298-
title: Text(data.dropFile!.path),
299-
subtitle: Text(data.type.toString()),
300-
);
380+
return ListTile(
381+
title: Text(data.dropFile!.path),
382+
subtitle: Text(data.type.toString()),
383+
);
384+
},
385+
));
301386
})
302387
: const Center(
303388
child: Text("Drop data here"),

0 commit comments

Comments
 (0)