├── .gitattributes
├── .gitignore
├── .idea
├── codeStyles
│ └── Project.xml
├── libraries
│ ├── Dart_Packages.xml
│ ├── Dart_SDK.xml
│ └── Flutter_Plugins.xml
├── markdown-navigator.xml
├── markdown-navigator
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
├── vcs.xml
└── workspace.xml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── demo.gif
├── draggable_flutter_list.iml
├── example
├── .gitignore
├── .idea
│ ├── codeStyles
│ │ └── Project.xml
│ ├── libraries
│ │ ├── Dart_Packages.xml
│ │ ├── Dart_SDK.xml
│ │ ├── Flutter_Plugins.xml
│ │ └── Flutter_for_Android.xml
│ ├── markdown-navigator.xml
│ ├── markdown-navigator
│ │ └── profiles_settings.xml
│ ├── misc.xml
│ ├── modules.xml
│ ├── runConfigurations
│ │ └── main_dart.xml
│ └── workspace.xml
├── .metadata
├── README.md
├── android
│ ├── .gitignore
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── realank
│ │ │ │ └── example
│ │ │ │ └── MainActivity.java
│ │ │ └── res
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ └── values
│ │ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── example.iml
├── example_android.iml
├── ios
│ ├── .gitignore
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── WorkspaceSettings.xcsettings
│ └── Runner
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── main.m
├── lib
│ └── main.dart
├── pubspec.lock
├── pubspec.yaml
└── test
│ └── widget_test.dart
├── lib
├── draggable_flutter_list.dart
├── draggable_list_item.dart
├── my_draggable.dart
└── tools.dart
├── pubspec.lock
├── pubspec.yaml
├── screenshot.jpg
└── test
└── draggable_flutter_list_test.dart
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 |
4 | .packages
5 | .pub/
6 |
7 | build/
8 | ios/.generated/
9 | ios/Flutter/Generated.xcconfig
10 | ios/Runner/GeneratedPluginRegistrant.*
11 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.idea/libraries/Dart_Packages.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
--------------------------------------------------------------------------------
/.idea/libraries/Dart_SDK.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/libraries/Flutter_Plugins.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [0.1.0] - release
2 | ## [0.1.1] - update readme
3 | ## [0.1.2] - add demo gif
4 | ## [0.1.3] - fix key issue
5 | ## [0.1.4] - fix hints
6 | ## [0.1.5] - add scroll controller property
7 | ## [0.1.6] - add scroll controller property
8 | ## [0.1.7] - fix bug when can't drop to an index
9 | ## [0.1.8] - fix dragging index bug
10 | ## [0.1.9] - pub.dartlang.org bug, can't analyze, re-submit
11 | ## [0.2.0] - improve performance
12 | ## [0.2.1] - fix dependencies
13 | ## [0.2.2] - format files
14 | ## [0.2.3] - format files
15 | ## [1.0.0] - release stable version
16 | ## [1.0.1] - fix out of bounds issue
17 | ## [1.0.2] - fix only one cell disappear when dragging issue
18 | ## [1.0.3] - typo packages name, dragable_flutter_list -> draggable_flutter_list
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Liu Yanbo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # draggable_flutter_list
2 |
3 | A flutter list view which can drag & move item to change order.
4 |
5 | - some codes come from [flutter_list_drag_and_drop](https://github.com/Norbert515/flutter_list_drag_and_drop)
6 | - fix flutter_list_drag_and_drop's dart version support
7 | - optimize data structure and api
8 | - drag and drop items in List View
9 | - drag and drop are optional for specific item
10 | - animate when dragging
11 |
12 | ### *Please use *draggable_flutter_list* for your dependency,
13 | The old name dragable_flutter_list (lack g) has been deprecated
14 |
15 | 
16 |
17 | ## Usage
18 |
19 | [Pub package](https://pub.dartlang.org/packages/draggable_flutter_list)
20 |
21 | ```dart
22 | import 'package:flutter/material.dart';
23 | import 'package:draggable_flutter_list/draggable_flutter_list.dart';
24 |
25 | void main() {
26 | runApp(new TestApp());
27 | }
28 |
29 | class TestApp extends StatelessWidget {
30 | TestApp({Key key});
31 |
32 | // This widget is the root of your application.
33 | @override
34 | Widget build(BuildContext context) {
35 | return new MaterialApp(
36 | title: 'Flutter Demo',
37 | theme: new ThemeData(primarySwatch: Colors.blue),
38 | home: new MyHomePage(
39 | title: 'Flutter Demo Home Page',
40 | key: key,
41 | ),
42 | );
43 | }
44 | }
45 |
46 | class MyHomePage extends StatefulWidget {
47 | MyHomePage({Key key, this.title}) : super(key: key);
48 | final String title;
49 |
50 | @override
51 | MyHomePageState createState() => new MyHomePageState();
52 | }
53 |
54 | class MyHomePageState extends State {
55 | List items = [
56 | '0',
57 | '1',
58 | 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.',
59 | '3',
60 | '4',
61 | 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.',
62 | '6',
63 | '7',
64 | '8',
65 | '9',
66 | '10',
67 | '11',
68 | '12',
69 | '13',
70 | '14',
71 | '15',
72 | ];
73 | @override
74 | Widget build(BuildContext context) {
75 | return new Scaffold(
76 | appBar: new AppBar(
77 | title: new Text(widget.title),
78 | ),
79 | body: new DragAndDropList(
80 | items.length,
81 | itemBuilder: (BuildContext context, index) {
82 | return new SizedBox(
83 | child: new Card(
84 | child: new ListTile(
85 | title: new Text(items[index]),
86 | ),
87 | ),
88 | );
89 | },
90 | onDragFinish: (before, after) {
91 | print('on drag finish $before $after');
92 | String data = items[before];
93 | items.removeAt(before);
94 | items.insert(after, data);
95 | },
96 | canDrag: (index) {
97 | print('can drag $index');
98 | return index != 3; //disable drag for index 3
99 | },
100 | canBeDraggedTo: (one, two) => true,
101 | dragElevation: 8.0,
102 | ),
103 | );
104 | }
105 | }
106 |
107 | ```
108 |
109 | ## Getting Started
110 |
111 | For help getting started with Flutter, view our online [documentation](https://flutter.io/).
112 |
113 | For help on editing package code, view the [documentation](https://flutter.io/developing-packages/).
114 |
--------------------------------------------------------------------------------
/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/demo.gif
--------------------------------------------------------------------------------
/draggable_flutter_list.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 |
4 | .packages
5 | .pub/
6 |
7 | build/
8 |
9 | .flutter-plugins
10 |
--------------------------------------------------------------------------------
/example/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/example/.idea/libraries/Dart_Packages.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
--------------------------------------------------------------------------------
/example/.idea/libraries/Dart_SDK.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/example/.idea/libraries/Flutter_Plugins.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/example/.idea/libraries/Flutter_for_Android.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/example/.idea/markdown-navigator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/example/.idea/markdown-navigator/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/example/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/example/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/example/.idea/runConfigurations/main_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/example/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 | 1535012481895
179 |
180 |
181 | 1535012481895
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
--------------------------------------------------------------------------------
/example/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 5cd97f0004707872e5e12bdb83b62fbc855b80c8
8 | channel: master
9 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # example
2 |
3 | A new Flutter application.
4 |
5 | ## Getting Started
6 |
7 | For help getting started with Flutter, view our online
8 | [documentation](https://flutter.io/).
9 |
--------------------------------------------------------------------------------
/example/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | *.class
3 | .gradle
4 | /local.properties
5 | /.idea/workspace.xml
6 | /.idea/libraries
7 | .DS_Store
8 | /build
9 | /captures
10 | GeneratedPluginRegistrant.java
11 |
--------------------------------------------------------------------------------
/example/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
26 |
27 | android {
28 | compileSdkVersion 27
29 |
30 | lintOptions {
31 | disable 'InvalidPackage'
32 | }
33 |
34 | defaultConfig {
35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
36 | applicationId "com.realank.example"
37 | minSdkVersion 16
38 | targetSdkVersion 27
39 | versionCode flutterVersionCode.toInteger()
40 | versionName flutterVersionName
41 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
42 | }
43 |
44 | buildTypes {
45 | release {
46 | // TODO: Add your own signing config for the release build.
47 | // Signing with the debug keys for now, so `flutter run --release` works.
48 | signingConfig signingConfigs.debug
49 | }
50 | }
51 | }
52 |
53 | flutter {
54 | source '../..'
55 | }
56 |
57 | dependencies {
58 | testImplementation 'junit:junit:4.12'
59 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
60 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
61 | }
62 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
15 |
19 |
26 |
30 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/realank/example/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.realank.example;
2 |
3 | import android.os.Bundle;
4 | import io.flutter.app.FlutterActivity;
5 | import io.flutter.plugins.GeneratedPluginRegistrant;
6 |
7 | public class MainActivity extends FlutterActivity {
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 | super.onCreate(savedInstanceState);
11 | GeneratedPluginRegistrant.registerWith(this);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | jcenter()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:3.1.2'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | google()
15 | jcenter()
16 | }
17 | }
18 |
19 | rootProject.buildDir = '../build'
20 | subprojects {
21 | project.buildDir = "${rootProject.buildDir}/${project.name}"
22 | }
23 | subprojects {
24 | project.evaluationDependsOn(':app')
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/example/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/example/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/example/example.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/example/example_android.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/example/ios/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .vagrant/
3 | .sconsign.dblite
4 | .svn/
5 |
6 | .DS_Store
7 | *.swp
8 | profile
9 |
10 | DerivedData/
11 | build/
12 | GeneratedPluginRegistrant.h
13 | GeneratedPluginRegistrant.m
14 |
15 | .generated/
16 |
17 | *.pbxuser
18 | *.mode1v3
19 | *.mode2v3
20 | *.perspectivev3
21 |
22 | !default.pbxuser
23 | !default.mode1v3
24 | !default.mode2v3
25 | !default.perspectivev3
26 |
27 | xcuserdata
28 |
29 | *.moved-aside
30 |
31 | *.pyc
32 | *sync/
33 | Icon?
34 | .tags*
35 |
36 | /Flutter/app.flx
37 | /Flutter/app.zip
38 | /Flutter/flutter_assets/
39 | /Flutter/App.framework
40 | /Flutter/Flutter.framework
41 | /Flutter/Generated.xcconfig
42 | /ServiceDefinitions.json
43 |
44 | Pods/
45 | .symlinks/
46 |
--------------------------------------------------------------------------------
/example/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; };
12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
13 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
14 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
15 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
16 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
17 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
18 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
19 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
20 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
21 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
22 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
23 | /* End PBXBuildFile section */
24 |
25 | /* Begin PBXCopyFilesBuildPhase section */
26 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
27 | isa = PBXCopyFilesBuildPhase;
28 | buildActionMask = 2147483647;
29 | dstPath = "";
30 | dstSubfolderSpec = 10;
31 | files = (
32 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
33 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
34 | );
35 | name = "Embed Frameworks";
36 | runOnlyForDeploymentPostprocessing = 0;
37 | };
38 | /* End PBXCopyFilesBuildPhase section */
39 |
40 | /* Begin PBXFileReference section */
41 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
42 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
43 | 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; };
44 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
45 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; };
46 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
47 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
48 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
49 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
50 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
51 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; };
52 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
53 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
54 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
55 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
56 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
57 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
58 | /* End PBXFileReference section */
59 |
60 | /* Begin PBXFrameworksBuildPhase section */
61 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
62 | isa = PBXFrameworksBuildPhase;
63 | buildActionMask = 2147483647;
64 | files = (
65 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
66 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
67 | );
68 | runOnlyForDeploymentPostprocessing = 0;
69 | };
70 | /* End PBXFrameworksBuildPhase section */
71 |
72 | /* Begin PBXGroup section */
73 | 9740EEB11CF90186004384FC /* Flutter */ = {
74 | isa = PBXGroup;
75 | children = (
76 | 2D5378251FAA1A9400D5DBA9 /* flutter_assets */,
77 | 3B80C3931E831B6300D905FE /* App.framework */,
78 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
79 | 9740EEBA1CF902C7004384FC /* Flutter.framework */,
80 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
81 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
82 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
83 | );
84 | name = Flutter;
85 | sourceTree = "";
86 | };
87 | 97C146E51CF9000F007C117D = {
88 | isa = PBXGroup;
89 | children = (
90 | 9740EEB11CF90186004384FC /* Flutter */,
91 | 97C146F01CF9000F007C117D /* Runner */,
92 | 97C146EF1CF9000F007C117D /* Products */,
93 | CF3B75C9A7D2FA2A4C99F110 /* Frameworks */,
94 | );
95 | sourceTree = "";
96 | };
97 | 97C146EF1CF9000F007C117D /* Products */ = {
98 | isa = PBXGroup;
99 | children = (
100 | 97C146EE1CF9000F007C117D /* Runner.app */,
101 | );
102 | name = Products;
103 | sourceTree = "";
104 | };
105 | 97C146F01CF9000F007C117D /* Runner */ = {
106 | isa = PBXGroup;
107 | children = (
108 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
109 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
110 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
111 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
112 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
113 | 97C147021CF9000F007C117D /* Info.plist */,
114 | 97C146F11CF9000F007C117D /* Supporting Files */,
115 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
116 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
117 | );
118 | path = Runner;
119 | sourceTree = "";
120 | };
121 | 97C146F11CF9000F007C117D /* Supporting Files */ = {
122 | isa = PBXGroup;
123 | children = (
124 | 97C146F21CF9000F007C117D /* main.m */,
125 | );
126 | name = "Supporting Files";
127 | sourceTree = "";
128 | };
129 | /* End PBXGroup section */
130 |
131 | /* Begin PBXNativeTarget section */
132 | 97C146ED1CF9000F007C117D /* Runner */ = {
133 | isa = PBXNativeTarget;
134 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
135 | buildPhases = (
136 | 9740EEB61CF901F6004384FC /* Run Script */,
137 | 97C146EA1CF9000F007C117D /* Sources */,
138 | 97C146EB1CF9000F007C117D /* Frameworks */,
139 | 97C146EC1CF9000F007C117D /* Resources */,
140 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
141 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
142 | );
143 | buildRules = (
144 | );
145 | dependencies = (
146 | );
147 | name = Runner;
148 | productName = Runner;
149 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
150 | productType = "com.apple.product-type.application";
151 | };
152 | /* End PBXNativeTarget section */
153 |
154 | /* Begin PBXProject section */
155 | 97C146E61CF9000F007C117D /* Project object */ = {
156 | isa = PBXProject;
157 | attributes = {
158 | LastUpgradeCheck = 0910;
159 | ORGANIZATIONNAME = "The Chromium Authors";
160 | TargetAttributes = {
161 | 97C146ED1CF9000F007C117D = {
162 | CreatedOnToolsVersion = 7.3.1;
163 | };
164 | };
165 | };
166 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
167 | compatibilityVersion = "Xcode 3.2";
168 | developmentRegion = English;
169 | hasScannedForEncodings = 0;
170 | knownRegions = (
171 | en,
172 | Base,
173 | );
174 | mainGroup = 97C146E51CF9000F007C117D;
175 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
176 | projectDirPath = "";
177 | projectRoot = "";
178 | targets = (
179 | 97C146ED1CF9000F007C117D /* Runner */,
180 | );
181 | };
182 | /* End PBXProject section */
183 |
184 | /* Begin PBXResourcesBuildPhase section */
185 | 97C146EC1CF9000F007C117D /* Resources */ = {
186 | isa = PBXResourcesBuildPhase;
187 | buildActionMask = 2147483647;
188 | files = (
189 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
190 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
191 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
192 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
193 | 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */,
194 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
195 | );
196 | runOnlyForDeploymentPostprocessing = 0;
197 | };
198 | /* End PBXResourcesBuildPhase section */
199 |
200 | /* Begin PBXShellScriptBuildPhase section */
201 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
202 | isa = PBXShellScriptBuildPhase;
203 | buildActionMask = 2147483647;
204 | files = (
205 | );
206 | inputPaths = (
207 | );
208 | name = "Thin Binary";
209 | outputPaths = (
210 | );
211 | runOnlyForDeploymentPostprocessing = 0;
212 | shellPath = /bin/sh;
213 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
214 | };
215 | 9740EEB61CF901F6004384FC /* Run Script */ = {
216 | isa = PBXShellScriptBuildPhase;
217 | buildActionMask = 2147483647;
218 | files = (
219 | );
220 | inputPaths = (
221 | );
222 | name = "Run Script";
223 | outputPaths = (
224 | );
225 | runOnlyForDeploymentPostprocessing = 0;
226 | shellPath = /bin/sh;
227 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
228 | };
229 | /* End PBXShellScriptBuildPhase section */
230 |
231 | /* Begin PBXSourcesBuildPhase section */
232 | 97C146EA1CF9000F007C117D /* Sources */ = {
233 | isa = PBXSourcesBuildPhase;
234 | buildActionMask = 2147483647;
235 | files = (
236 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
237 | 97C146F31CF9000F007C117D /* main.m in Sources */,
238 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
239 | );
240 | runOnlyForDeploymentPostprocessing = 0;
241 | };
242 | /* End PBXSourcesBuildPhase section */
243 |
244 | /* Begin PBXVariantGroup section */
245 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
246 | isa = PBXVariantGroup;
247 | children = (
248 | 97C146FB1CF9000F007C117D /* Base */,
249 | );
250 | name = Main.storyboard;
251 | sourceTree = "";
252 | };
253 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
254 | isa = PBXVariantGroup;
255 | children = (
256 | 97C147001CF9000F007C117D /* Base */,
257 | );
258 | name = LaunchScreen.storyboard;
259 | sourceTree = "";
260 | };
261 | /* End PBXVariantGroup section */
262 |
263 | /* Begin XCBuildConfiguration section */
264 | 97C147031CF9000F007C117D /* Debug */ = {
265 | isa = XCBuildConfiguration;
266 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
267 | buildSettings = {
268 | ALWAYS_SEARCH_USER_PATHS = NO;
269 | CLANG_ANALYZER_NONNULL = YES;
270 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
271 | CLANG_CXX_LIBRARY = "libc++";
272 | CLANG_ENABLE_MODULES = YES;
273 | CLANG_ENABLE_OBJC_ARC = YES;
274 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
275 | CLANG_WARN_BOOL_CONVERSION = YES;
276 | CLANG_WARN_COMMA = YES;
277 | CLANG_WARN_CONSTANT_CONVERSION = YES;
278 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
279 | CLANG_WARN_EMPTY_BODY = YES;
280 | CLANG_WARN_ENUM_CONVERSION = YES;
281 | CLANG_WARN_INFINITE_RECURSION = YES;
282 | CLANG_WARN_INT_CONVERSION = YES;
283 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
284 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
285 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
286 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
287 | CLANG_WARN_STRICT_PROTOTYPES = YES;
288 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
289 | CLANG_WARN_UNREACHABLE_CODE = YES;
290 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
291 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
292 | COPY_PHASE_STRIP = NO;
293 | DEBUG_INFORMATION_FORMAT = dwarf;
294 | ENABLE_STRICT_OBJC_MSGSEND = YES;
295 | ENABLE_TESTABILITY = YES;
296 | GCC_C_LANGUAGE_STANDARD = gnu99;
297 | GCC_DYNAMIC_NO_PIC = NO;
298 | GCC_NO_COMMON_BLOCKS = YES;
299 | GCC_OPTIMIZATION_LEVEL = 0;
300 | GCC_PREPROCESSOR_DEFINITIONS = (
301 | "DEBUG=1",
302 | "$(inherited)",
303 | );
304 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
305 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
306 | GCC_WARN_UNDECLARED_SELECTOR = YES;
307 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
308 | GCC_WARN_UNUSED_FUNCTION = YES;
309 | GCC_WARN_UNUSED_VARIABLE = YES;
310 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
311 | MTL_ENABLE_DEBUG_INFO = YES;
312 | ONLY_ACTIVE_ARCH = YES;
313 | SDKROOT = iphoneos;
314 | TARGETED_DEVICE_FAMILY = "1,2";
315 | };
316 | name = Debug;
317 | };
318 | 97C147041CF9000F007C117D /* Release */ = {
319 | isa = XCBuildConfiguration;
320 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
321 | buildSettings = {
322 | ALWAYS_SEARCH_USER_PATHS = NO;
323 | CLANG_ANALYZER_NONNULL = YES;
324 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
325 | CLANG_CXX_LIBRARY = "libc++";
326 | CLANG_ENABLE_MODULES = YES;
327 | CLANG_ENABLE_OBJC_ARC = YES;
328 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
329 | CLANG_WARN_BOOL_CONVERSION = YES;
330 | CLANG_WARN_COMMA = YES;
331 | CLANG_WARN_CONSTANT_CONVERSION = YES;
332 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
333 | CLANG_WARN_EMPTY_BODY = YES;
334 | CLANG_WARN_ENUM_CONVERSION = YES;
335 | CLANG_WARN_INFINITE_RECURSION = YES;
336 | CLANG_WARN_INT_CONVERSION = YES;
337 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
338 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
339 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
340 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
341 | CLANG_WARN_STRICT_PROTOTYPES = YES;
342 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
343 | CLANG_WARN_UNREACHABLE_CODE = YES;
344 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
345 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
346 | COPY_PHASE_STRIP = NO;
347 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
348 | ENABLE_NS_ASSERTIONS = NO;
349 | ENABLE_STRICT_OBJC_MSGSEND = YES;
350 | GCC_C_LANGUAGE_STANDARD = gnu99;
351 | GCC_NO_COMMON_BLOCKS = YES;
352 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
353 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
354 | GCC_WARN_UNDECLARED_SELECTOR = YES;
355 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
356 | GCC_WARN_UNUSED_FUNCTION = YES;
357 | GCC_WARN_UNUSED_VARIABLE = YES;
358 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
359 | MTL_ENABLE_DEBUG_INFO = NO;
360 | SDKROOT = iphoneos;
361 | TARGETED_DEVICE_FAMILY = "1,2";
362 | VALIDATE_PRODUCT = YES;
363 | };
364 | name = Release;
365 | };
366 | 97C147061CF9000F007C117D /* Debug */ = {
367 | isa = XCBuildConfiguration;
368 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
369 | buildSettings = {
370 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
371 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
372 | ENABLE_BITCODE = NO;
373 | FRAMEWORK_SEARCH_PATHS = (
374 | "$(inherited)",
375 | "$(PROJECT_DIR)/Flutter",
376 | );
377 | INFOPLIST_FILE = Runner/Info.plist;
378 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
379 | LIBRARY_SEARCH_PATHS = (
380 | "$(inherited)",
381 | "$(PROJECT_DIR)/Flutter",
382 | );
383 | PRODUCT_BUNDLE_IDENTIFIER = com.realank.example;
384 | PRODUCT_NAME = "$(TARGET_NAME)";
385 | VERSIONING_SYSTEM = "apple-generic";
386 | };
387 | name = Debug;
388 | };
389 | 97C147071CF9000F007C117D /* Release */ = {
390 | isa = XCBuildConfiguration;
391 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
392 | buildSettings = {
393 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
394 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
395 | ENABLE_BITCODE = NO;
396 | FRAMEWORK_SEARCH_PATHS = (
397 | "$(inherited)",
398 | "$(PROJECT_DIR)/Flutter",
399 | );
400 | INFOPLIST_FILE = Runner/Info.plist;
401 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
402 | LIBRARY_SEARCH_PATHS = (
403 | "$(inherited)",
404 | "$(PROJECT_DIR)/Flutter",
405 | );
406 | PRODUCT_BUNDLE_IDENTIFIER = com.realank.example;
407 | PRODUCT_NAME = "$(TARGET_NAME)";
408 | VERSIONING_SYSTEM = "apple-generic";
409 | };
410 | name = Release;
411 | };
412 | /* End XCBuildConfiguration section */
413 |
414 | /* Begin XCConfigurationList section */
415 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
416 | isa = XCConfigurationList;
417 | buildConfigurations = (
418 | 97C147031CF9000F007C117D /* Debug */,
419 | 97C147041CF9000F007C117D /* Release */,
420 | );
421 | defaultConfigurationIsVisible = 0;
422 | defaultConfigurationName = Release;
423 | };
424 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
425 | isa = XCConfigurationList;
426 | buildConfigurations = (
427 | 97C147061CF9000F007C117D /* Debug */,
428 | 97C147071CF9000F007C117D /* Release */,
429 | );
430 | defaultConfigurationIsVisible = 0;
431 | defaultConfigurationName = Release;
432 | };
433 | /* End XCConfigurationList section */
434 | };
435 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
436 | }
437 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
56 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
75 |
77 |
83 |
84 |
85 |
86 |
88 |
89 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildSystemType
6 | Original
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : FlutterAppDelegate
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #include "AppDelegate.h"
2 | #include "GeneratedPluginRegistrant.h"
3 |
4 | @implementation AppDelegate
5 |
6 | - (BOOL)application:(UIApplication *)application
7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
8 | [GeneratedPluginRegistrant registerWithRegistry:self];
9 | // Override point for customization after application launch.
10 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
11 | }
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | example
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/example/ios/Runner/main.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char* argv[]) {
6 | @autoreleasepool {
7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:draggable_flutter_list/draggable_flutter_list.dart';
3 |
4 | void main() {
5 | runApp(new TestApp());
6 | }
7 |
8 | class TestApp extends StatelessWidget {
9 | TestApp({Key key});
10 |
11 | // This widget is the root of your application.
12 | @override
13 | Widget build(BuildContext context) {
14 | return new MaterialApp(
15 | title: 'Flutter Demo',
16 | theme: new ThemeData(primarySwatch: Colors.blue),
17 | home: new MyHomePage(
18 | title: 'Flutter Demo Home Page',
19 | key: key,
20 | ),
21 | );
22 | }
23 | }
24 |
25 | class MyHomePage extends StatefulWidget {
26 | MyHomePage({Key key, this.title}) : super(key: key);
27 | final String title;
28 |
29 | @override
30 | MyHomePageState createState() => new MyHomePageState();
31 | }
32 |
33 | class MyHomePageState extends State {
34 | List items = [
35 | '0',
36 | '1sfsdfdsfdsfsafafsafdsafsadfdsfdsfsafafsafdsafsadfdsfdsfsafafsafdsafsadfdsfdsfsafafsafdsafsadfdsfdsfsafafsafdsafsadfdsfdsfsafafsafdsafsadfdsfdsfsafafsafdsafsadfdsfdsfsafafsafdsafsadfdsfdsfsafafsafdsafsadfdsfdsfsafafsafdsafsadfdsfdsfsafafsafdsafsadfsadf',
37 | 'd'
38 | ];
39 | @override
40 | Widget build(BuildContext context) {
41 | return new Scaffold(
42 | appBar: new AppBar(
43 | title: new Text(widget.title),
44 | ),
45 | body: new DragAndDropList(
46 | items.length,
47 | itemBuilder: (BuildContext context, index) {
48 | return new SizedBox(
49 | child: new Card(
50 | child: new ListTile(
51 | title: new Text(items[index]),
52 | ),
53 | ),
54 | );
55 | },
56 | onDragFinish: (before, after) {
57 | String data = items[before];
58 | items.removeAt(before);
59 | items.insert(after, data);
60 | },
61 | canDrag: (index) {
62 | return index < 5; //disable drag for index 3
63 | },
64 | canBeDraggedTo: (from, to) {
65 | return to < 5;
66 | },
67 | dragElevation: 8.0,
68 | ),
69 | );
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/example/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://www.dartlang.org/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "2.0.8"
11 | boolean_selector:
12 | dependency: transitive
13 | description:
14 | name: boolean_selector
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "1.0.4"
18 | charcode:
19 | dependency: transitive
20 | description:
21 | name: charcode
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "1.1.2"
25 | collection:
26 | dependency: transitive
27 | description:
28 | name: collection
29 | url: "https://pub.dartlang.org"
30 | source: hosted
31 | version: "1.14.11"
32 | cupertino_icons:
33 | dependency: "direct main"
34 | description:
35 | name: cupertino_icons
36 | url: "https://pub.dartlang.org"
37 | source: hosted
38 | version: "0.1.2"
39 | draggable_flutter_list:
40 | dependency: "direct main"
41 | description:
42 | path: ".."
43 | relative: true
44 | source: path
45 | version: "1.0.2"
46 | flutter:
47 | dependency: "direct main"
48 | description: flutter
49 | source: sdk
50 | version: "0.0.0"
51 | flutter_test:
52 | dependency: "direct dev"
53 | description: flutter
54 | source: sdk
55 | version: "0.0.0"
56 | matcher:
57 | dependency: transitive
58 | description:
59 | name: matcher
60 | url: "https://pub.dartlang.org"
61 | source: hosted
62 | version: "0.12.3+1"
63 | meta:
64 | dependency: transitive
65 | description:
66 | name: meta
67 | url: "https://pub.dartlang.org"
68 | source: hosted
69 | version: "1.1.6"
70 | path:
71 | dependency: transitive
72 | description:
73 | name: path
74 | url: "https://pub.dartlang.org"
75 | source: hosted
76 | version: "1.6.2"
77 | quiver:
78 | dependency: transitive
79 | description:
80 | name: quiver
81 | url: "https://pub.dartlang.org"
82 | source: hosted
83 | version: "2.0.1"
84 | sky_engine:
85 | dependency: transitive
86 | description: flutter
87 | source: sdk
88 | version: "0.0.99"
89 | source_span:
90 | dependency: transitive
91 | description:
92 | name: source_span
93 | url: "https://pub.dartlang.org"
94 | source: hosted
95 | version: "1.4.1"
96 | stack_trace:
97 | dependency: transitive
98 | description:
99 | name: stack_trace
100 | url: "https://pub.dartlang.org"
101 | source: hosted
102 | version: "1.9.3"
103 | stream_channel:
104 | dependency: transitive
105 | description:
106 | name: stream_channel
107 | url: "https://pub.dartlang.org"
108 | source: hosted
109 | version: "1.6.8"
110 | string_scanner:
111 | dependency: transitive
112 | description:
113 | name: string_scanner
114 | url: "https://pub.dartlang.org"
115 | source: hosted
116 | version: "1.0.4"
117 | term_glyph:
118 | dependency: transitive
119 | description:
120 | name: term_glyph
121 | url: "https://pub.dartlang.org"
122 | source: hosted
123 | version: "1.0.1"
124 | test_api:
125 | dependency: transitive
126 | description:
127 | name: test_api
128 | url: "https://pub.dartlang.org"
129 | source: hosted
130 | version: "0.2.1"
131 | typed_data:
132 | dependency: transitive
133 | description:
134 | name: typed_data
135 | url: "https://pub.dartlang.org"
136 | source: hosted
137 | version: "1.1.6"
138 | vector_math:
139 | dependency: transitive
140 | description:
141 | name: vector_math
142 | url: "https://pub.dartlang.org"
143 | source: hosted
144 | version: "2.0.8"
145 | sdks:
146 | dart: ">=2.0.0 <3.0.0"
147 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: example
2 | description: A new Flutter application.
3 |
4 | # The following defines the version and build number for your application.
5 | # A version number is three numbers separated by dots, like 1.2.43
6 | # followed by an optional build number separated by a +.
7 | # Both the version and the builder number may be overridden in flutter
8 | # build by specifying --build-name and --build-number, respectively.
9 | # Read more about versioning at semver.org.
10 | version: 1.0.0+1
11 |
12 | environment:
13 | sdk: ">=2.0.0-dev.68.0 <3.0.0"
14 |
15 | dependencies:
16 | flutter:
17 | sdk: flutter
18 |
19 | # The following adds the Cupertino Icons font to your application.
20 | # Use with the CupertinoIcons class for iOS style icons.
21 | cupertino_icons: ^0.1.2
22 | draggable_flutter_list:
23 | path: ../
24 |
25 | dev_dependencies:
26 | flutter_test:
27 | sdk: flutter
28 |
29 |
30 | # For information on the generic Dart part of this file, see the
31 | # following page: https://www.dartlang.org/tools/pub/pubspec
32 |
33 | # The following section is specific to Flutter.
34 | flutter:
35 |
36 | # The following line ensures that the Material Icons font is
37 | # included with your application, so that you can use the icons in
38 | # the material Icons class.
39 | uses-material-design: true
40 |
41 | # To add assets to your application, add an assets section, like this:
42 | # assets:
43 | # - images/a_dot_burr.jpeg
44 | # - images/a_dot_ham.jpeg
45 |
46 | # An image asset can refer to one or more resolution-specific "variants", see
47 | # https://flutter.io/assets-and-images/#resolution-aware.
48 |
49 | # For details regarding adding assets from package dependencies, see
50 | # https://flutter.io/assets-and-images/#from-packages
51 |
52 | # To add custom fonts to your application, add a fonts section here,
53 | # in this "flutter" section. Each entry in this list should have a
54 | # "family" key with the font family name, and a "fonts" key with a
55 | # list giving the asset and other descriptors for the font. For
56 | # example:
57 | # fonts:
58 | # - family: Schyler
59 | # fonts:
60 | # - asset: fonts/Schyler-Regular.ttf
61 | # - asset: fonts/Schyler-Italic.ttf
62 | # style: italic
63 | # - family: Trajan Pro
64 | # fonts:
65 | # - asset: fonts/TrajanPro.ttf
66 | # - asset: fonts/TrajanPro_Bold.ttf
67 | # weight: 700
68 | #
69 | # For details regarding fonts from package dependencies,
70 | # see https://flutter.io/custom-fonts/#from-packages
71 |
--------------------------------------------------------------------------------
/example/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | // To perform an interaction with a widget in your test, use the WidgetTester utility that Flutter
3 | // provides. For example, you can send tap and scroll gestures. You can also use WidgetTester to
4 | // find child widgets in the widget tree, read text, and verify that the values of widget properties
5 | // are correct.
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter_test/flutter_test.dart';
9 |
10 | import 'package:example/main.dart';
11 |
12 | void main() {
13 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
14 | // Build our app and trigger a frame.
15 | await tester.pumpWidget(new TestApp());
16 |
17 | // Verify that our counter starts at 0.
18 | expect(find.text('0'), findsOneWidget);
19 | expect(find.text('1'), findsNothing);
20 |
21 | // Tap the '+' icon and trigger a frame.
22 | await tester.tap(find.byIcon(Icons.add));
23 | await tester.pump();
24 |
25 | // Verify that our counter has incremented.
26 | expect(find.text('0'), findsNothing);
27 | expect(find.text('1'), findsOneWidget);
28 | });
29 | }
30 |
--------------------------------------------------------------------------------
/lib/draggable_flutter_list.dart:
--------------------------------------------------------------------------------
1 | library draggable_flutter_list;
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/animation.dart';
5 | import 'package:flutter/rendering.dart';
6 | import 'draggable_list_item.dart';
7 | import 'tools.dart';
8 |
9 | typedef Widget WidgetMaker(BuildContext context, int index);
10 |
11 | class DragAndDropList extends StatefulWidget {
12 | final int rowsCount;
13 |
14 | final WidgetMaker itemBuilder;
15 |
16 | final CanDrag canDrag;
17 |
18 | final OnDragFinish onDragFinish;
19 |
20 | final CanAccept canBeDraggedTo;
21 |
22 | // dragElevation is only used if isItemsHaveCustomDraggableBehavior=false.
23 | // Otherwise, draggable items provide their own elevation/shadow.
24 | final double dragElevation;
25 |
26 | final ScrollController scrollController;
27 |
28 | DragAndDropList(this.rowsCount,
29 | {Key key,
30 | @required this.itemBuilder,
31 | this.onDragFinish,
32 | @required this.canBeDraggedTo,
33 | this.dragElevation = 0.0,
34 | this.canDrag,
35 | scrollController})
36 | : this.scrollController = scrollController ?? ScrollController(),
37 | super(key: key);
38 |
39 | @override
40 | State createState() => new _DragAndDropListState();
41 | }
42 |
43 | class _DragAndDropListState extends State {
44 | final double _kScrollThreshold = 160.0;
45 |
46 | bool shouldScrollUp = false;
47 | bool shouldScrollDown = false;
48 |
49 | double _currentScrollPos = 0.0;
50 |
51 | List rows = new List();
52 |
53 | //Index of the item dragged
54 | int _currentDraggingIndex;
55 |
56 | // The height of the item being dragged
57 | double dragHeight;
58 |
59 | SliverMultiBoxAdaptorElement renderSliverContext;
60 |
61 | Offset _currentMiddle;
62 |
63 | //Index of the item currently accepting
64 | int _currentIndex;
65 |
66 | bool isScrolling = false;
67 |
68 | double offsetToStartOfItem = 0.0;
69 |
70 | double sliverStartPos = 0.0;
71 |
72 | bool didJustStartDragging = false;
73 |
74 | // This corrects the case when the user grabs the card at the bottom, the system will always handle like grabbed on the middle to ensure correct behvior
75 | double middleOfItemInGlobalPosition = 0.0;
76 |
77 | @override
78 | void initState() {
79 | super.initState();
80 | populateRowList();
81 | }
82 |
83 | void populateRowList() {
84 | rows = [];
85 | for (int i = 0; i < widget.rowsCount; i++) {
86 | rows.add(Data(i));
87 | }
88 | }
89 |
90 | void _maybeScroll() {
91 | if (isScrolling) return;
92 |
93 | if (shouldScrollUp) {
94 | if (widget.scrollController.position.pixels == 0.0) return;
95 | isScrolling = true;
96 | var scrollTo = widget.scrollController.offset - 12.0;
97 | widget.scrollController
98 | .animateTo(scrollTo, duration: new Duration(milliseconds: 74), curve: Curves.linear)
99 | .then((it) {
100 | updatePlaceholder();
101 | isScrolling = false;
102 | _maybeScroll();
103 | });
104 | //TODO implement
105 | // Scrollable.ensureVisible(context, );
106 | }
107 | if (shouldScrollDown) {
108 | if (widget.scrollController.position.pixels ==
109 | widget.scrollController.position.maxScrollExtent) return;
110 | isScrolling = true;
111 | var scrollTo = widget.scrollController.offset + 12.0;
112 | widget.scrollController
113 | .animateTo(scrollTo, duration: new Duration(milliseconds: 75), curve: Curves.linear)
114 | .then((it) {
115 | updatePlaceholder();
116 | isScrolling = false;
117 | _maybeScroll();
118 | });
119 | }
120 | }
121 |
122 | @override
123 | void didUpdateWidget(DragAndDropList oldWidget) {
124 | super.didUpdateWidget(oldWidget);
125 | populateRowList();
126 | }
127 |
128 | @override
129 | Widget build(BuildContext context) {
130 | return new LayoutBuilder(
131 | builder: (BuildContext context3, constr) {
132 | return new ListView.builder(
133 | itemBuilder: (BuildContext context2, int index) {
134 | return _getDraggableListItem(context2, index, context3);
135 | },
136 | controller: widget.scrollController,
137 | itemCount: rows.length,
138 | );
139 | },
140 | );
141 | }
142 |
143 | Widget _getDraggableListItem(BuildContext context2, int index, BuildContext context3) {
144 | var draggableListItem = new DraggableListItem(
145 | child: widget.itemBuilder(context2, rows[index].index),
146 | key: new ValueKey(rows[index]),
147 | data: rows[index],
148 | index: index,
149 | dragElevation: widget.dragElevation,
150 | draggedHeight: dragHeight,
151 | canDrag: widget.canDrag,
152 | onDragStarted: (double draggedHeight, double globalTopPositionOfDraggedItem) {
153 | _currentDraggingIndex = index;
154 | RenderBox rend = context3.findRenderObject();
155 | double start = rend.localToGlobal(new Offset(0.0, 0.0)).dy;
156 | // double end = rend.localToGlobal(new Offset(0.0, rend.semanticBounds.height)).dy;
157 |
158 | didJustStartDragging = true;
159 | _currentScrollPos = start;
160 |
161 | middleOfItemInGlobalPosition = globalTopPositionOfDraggedItem + draggedHeight / 2;
162 |
163 | sliverStartPos = start;
164 |
165 | // _buildOverlay(context2, start, end);
166 |
167 | renderSliverContext = context2;
168 | updatePlaceholder();
169 | dragHeight = draggedHeight;
170 |
171 | setState(() {
172 | rows.removeAt(index);
173 | });
174 | },
175 | onDragCompleted: () {
176 | _accept(index, _currentDraggingIndex);
177 | },
178 | onAccept: (int index) {
179 | _accept(_currentIndex, index);
180 | },
181 | onMove: (Offset offset) {
182 | if (didJustStartDragging) {
183 | didJustStartDragging = false;
184 | offsetToStartOfItem = offset.dy - middleOfItemInGlobalPosition;
185 | _currentScrollPos = offset.dy - offsetToStartOfItem;
186 | }
187 | _currentScrollPos = offset.dy - offsetToStartOfItem;
188 | double screenHeight = MediaQuery.of(context2).size.height;
189 |
190 | if (_currentScrollPos < _kScrollThreshold) {
191 | shouldScrollUp = true;
192 | } else {
193 | shouldScrollUp = false;
194 | }
195 | if (_currentScrollPos > screenHeight - _kScrollThreshold) {
196 | shouldScrollDown = true;
197 | } else {
198 | shouldScrollDown = false;
199 | }
200 | _maybeScroll();
201 | updatePlaceholder();
202 | },
203 | cancelCallback: () {
204 | _accept(_currentIndex, _currentDraggingIndex);
205 | },
206 | );
207 | return draggableListItem;
208 | }
209 |
210 | void _complete() {
211 | shouldScrollUp = false;
212 | shouldScrollDown = false;
213 | _currentIndex = null;
214 | _currentScrollPos = 0.0;
215 | _currentMiddle = null;
216 | _currentDraggingIndex = null;
217 | didJustStartDragging = false;
218 | offsetToStartOfItem = 0.0;
219 | middleOfItemInGlobalPosition = 0.0;
220 | }
221 |
222 | void _accept(int toIndex, int fromIndex) {
223 | if (_currentIndex == null || _currentMiddle == null) {
224 | setState(() {
225 | populateRowList();
226 | });
227 | _complete();
228 | return;
229 | }
230 | setState(() {
231 | shouldScrollDown = false;
232 | shouldScrollUp = false;
233 | if (fromIndex < rows.length) {
234 | rows[fromIndex].extraHeight = 0.0;
235 | }
236 |
237 | if (_currentMiddle.dy >= _currentScrollPos || rows.length == 0) {
238 | widget.onDragFinish(_currentDraggingIndex, toIndex);
239 | } else {
240 | widget.onDragFinish(_currentDraggingIndex, toIndex + 1);
241 | }
242 | populateRowList();
243 | });
244 | _complete();
245 | }
246 |
247 | void updatePlaceholder() {
248 | if (renderSliverContext == null) return;
249 | if (_currentDraggingIndex == null) return;
250 | RenderSliverList it = renderSliverContext.findRenderObject();
251 | double buffer = sliverStartPos;
252 | RenderBox currentChild = it.firstChild;
253 | print('current child $currentChild');
254 | if (currentChild == null) {
255 | return;
256 | }
257 | buffer += it.childMainAxisPosition(currentChild) + currentChild.size.height;
258 | while (_currentScrollPos > buffer) {
259 | if (currentChild != null) {
260 | var bufferChild = it.childAfter(currentChild);
261 | if (bufferChild == null) break;
262 | currentChild = bufferChild;
263 | buffer = it.childMainAxisPosition(currentChild) + currentChild.size.height + sliverStartPos;
264 | }
265 | }
266 | double middle = buffer - currentChild.size.height / 2;
267 |
268 | int index = it.indexOf(currentChild);
269 |
270 | if (!widget.canBeDraggedTo(_currentDraggingIndex, index)) return;
271 |
272 | _currentMiddle = new Offset(0.0, middle);
273 |
274 | final previousIndex = _currentIndex;
275 | final nextIndex = index;
276 | _currentIndex = index;
277 | final atTop = _currentScrollPos <= _currentMiddle.dy;
278 |
279 | if (nextIndex < rows.length &&
280 | previousIndex == nextIndex &&
281 | rows[nextIndex].isExtraAtTop == atTop &&
282 | rows[nextIndex].extraHeight == dragHeight) {
283 | return;
284 | }
285 |
286 | bool needUpdate = false;
287 |
288 | if (previousIndex != null && previousIndex < rows.length) {
289 | if (rows[previousIndex].extraHeight > 0.1) {
290 | rows[previousIndex].extraHeight = 0.0;
291 | needUpdate = true;
292 | }
293 | }
294 |
295 | if (nextIndex < rows.length) {
296 | if (dragHeight != null &&
297 | (absMinus(rows[nextIndex].extraHeight, dragHeight) > 0.1 ||
298 | rows[nextIndex].isExtraAtTop != atTop)) {
299 | rows[nextIndex].extraHeight = dragHeight;
300 | rows[nextIndex].isExtraAtTop = atTop;
301 | needUpdate = true;
302 | }
303 | }
304 |
305 | if (needUpdate) {
306 | setState(() {});
307 | }
308 | }
309 | }
310 |
--------------------------------------------------------------------------------
/lib/draggable_list_item.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'my_draggable.dart';
3 | //import 'tools.dart';
4 |
5 | typedef void OnDragStarted(double height, double topPosition);
6 | typedef void OnDragFinish(int oldIndex, int newIndex);
7 | typedef bool CanAccept(int oldIndex, int newIndex);
8 | typedef bool CanDrag(int index);
9 |
10 | class DraggableListItem extends StatelessWidget {
11 | final Data data;
12 | final int index;
13 |
14 | final double draggedHeight;
15 | final CanDrag canDrag;
16 | final OnDragStarted onDragStarted;
17 | final VoidCallback onDragCompleted;
18 | final MyDragTargetAccept onAccept;
19 | final ValueChanged onMove;
20 | final VoidCallback cancelCallback;
21 |
22 | final double dragElevation;
23 |
24 | final Widget child;
25 |
26 | DraggableListItem({
27 | Key key,
28 | this.data,
29 | this.index,
30 | this.canDrag,
31 | this.onDragStarted,
32 | this.onDragCompleted,
33 | this.onAccept,
34 | this.onMove,
35 | this.cancelCallback,
36 | this.draggedHeight,
37 | this.child,
38 | this.dragElevation,
39 | }) : super(key: key);
40 |
41 | @override
42 | Widget build(BuildContext context) {
43 | if (canDrag != null && !(canDrag(index))) {
44 | return _getListChild(context);
45 | } else {
46 | return LongPressMyDraggable(
47 | key: key,
48 | child: _getListChild(context),
49 | feedback: _getFeedback(index, context),
50 | data: data,
51 | onMove: onMove,
52 | onDragStarted: () {
53 | RenderBox it = context.findRenderObject() as RenderBox;
54 | onDragStarted(it.size.height,
55 | it.localToGlobal(it.semanticBounds.topCenter).dy);
56 | },
57 | onDragCompleted: onDragCompleted,
58 | onMyDraggableCanceled: (_, _2) {
59 | cancelCallback();
60 | });
61 | }
62 | }
63 |
64 | Widget _getListChild(BuildContext context) {
65 | double nextTop = 0.0;
66 | double nextBot = 0.0;
67 | if (data.isExtraAtTop) {
68 | nextTop = data.extraHeight;
69 | } else {
70 | nextBot = data.extraHeight;
71 | }
72 |
73 | return MyDragTarget(
74 | builder: (BuildContext context, List candidateData, List rejectedData) {
75 | return Column(
76 | children: [
77 | SizedBox(
78 | height: nextTop,
79 | ),
80 | child,
81 | SizedBox(
82 | height: nextBot,
83 | ),
84 | ],
85 | );
86 | },
87 | onAccept: onAccept,
88 | onWillAccept: (data) {
89 | return true;
90 | },
91 | );
92 | }
93 |
94 | Widget _getFeedback(int index, BuildContext context) {
95 | var maxWidth = MediaQuery.of(context).size.width;
96 | return ConstrainedBox(
97 | constraints: BoxConstraints(maxWidth: maxWidth),
98 | child: Transform(
99 | transform: Matrix4.rotationZ(0.0),
100 | alignment: FractionalOffset.bottomRight,
101 | child: Material(
102 | child: child,
103 | elevation: dragElevation,
104 | color: Colors.transparent,
105 | borderRadius: BorderRadius.zero,
106 | ),
107 | ),
108 | );
109 | }
110 | }
111 |
112 | class Data {
113 | int index;
114 | double extraHeight;
115 | bool isExtraAtTop;
116 |
117 | Data(
118 | this.index, {
119 | this.isExtraAtTop = true,
120 | this.extraHeight = 0.0,
121 | });
122 | }
123 |
--------------------------------------------------------------------------------
/lib/my_draggable.dart:
--------------------------------------------------------------------------------
1 | // Copyright 2015 The Chromium Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | import 'package:flutter/foundation.dart';
6 | import 'package:flutter/gestures.dart';
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter/rendering.dart';
9 | //import 'package:flutter/services.dart';
10 |
11 | /// Signature for determining whether the given data will be accepted by a [MyDragTarget].
12 | ///
13 | /// Used by [MyDragTarget.onWillAccept].
14 | typedef bool MyDragTargetWillAccept(T data);
15 |
16 | /// Signature for causing a [MyDragTarget] to accept the given data.
17 | ///
18 | /// Used by [MyDragTarget.onAccept].
19 | typedef void MyDragTargetAccept(int index);
20 |
21 | /// Signature for building children of a [MyDragTarget].
22 | ///
23 | /// The `candidateData` argument contains the list of drag data that is hovering
24 | /// over this [MyDragTarget] and that has passed [MyDragTarget.onWillAccept]. The
25 | /// `rejectedData` argument contains the list of drag data that is hovering over
26 | /// this [MyDragTarget] and that will not be accepted by the [MyDragTarget].
27 | ///
28 | /// Used by [MyDragTarget.builder].
29 | typedef Widget MyDragTargetBuilder(
30 | BuildContext context, List candidateData, List rejectedData);
31 |
32 | /// Signature for when a [MyDraggable] is dropped without being accepted by a [MyDragTarget].
33 | ///
34 | /// Used by [MyDraggable.onMyDraggableCanceled].
35 | typedef void MyDraggableCanceledCallback(Velocity velocity, Offset offset);
36 |
37 | /// Signature for when a [MyDraggable] leaves a [MyDragTarget].
38 | ///
39 | /// Used by [MyDragTarget.onLeave].
40 | typedef void MyDragTargetLeave(T data);
41 |
42 | /// Where the [MyDraggable] should be anchored during a drag.
43 | enum DragAnchor {
44 | /// Display the feedback anchored at the position of the original child. If
45 | /// feedback is identical to the child, then this means the feedback will
46 | /// exactly overlap the original child when the drag starts.
47 | child,
48 |
49 | /// Display the feedback anchored at the position of the touch that started
50 | /// the drag. If feedback is identical to the child, then this means the top
51 | /// left of the feedback will be under the finger when the drag starts. This
52 | /// will likely not exactly overlap the original child, e.g. if the child is
53 | /// big and the touch was not centered. This mode is useful when the feedback
54 | /// is transformed so as to move the feedback to the left by half its width,
55 | /// and up by half its width plus the height of the finger, since then it
56 | /// appears as if putting the finger down makes the touch feedback appear
57 | /// above the finger. (It feels weird for it to appear offset from the
58 | /// original child if it's anchored to the child and not the finger.)
59 | pointer,
60 | }
61 |
62 | /// A widget that can be dragged from to a [MyDragTarget].
63 | ///
64 | /// When a MyDraggable widget recognizes the start of a drag gesture, it displays
65 | /// a [feedback] widget that tracks the user's finger across the screen. If the
66 | /// user lifts their finger while on top of a [MyDragTarget], that target is given
67 | /// the opportunity to accept the [data] carried by the MyDraggable.
68 | ///
69 | /// On multitouch devices, multiple drags can occur simultaneously because there
70 | /// can be multiple pointers in contact with the device at once. To limit the
71 | /// number of simultaneous drags, use the [maxSimultaneousDrags] property. The
72 | /// default is to allow an unlimited number of simultaneous drags.
73 | ///
74 | /// This widget displays [child] when zero drags are under way. If
75 | /// [childWhenDragging] is non-null, this widget instead displays
76 | /// [childWhenDragging] when one or more drags are underway. Otherwise, this
77 | /// widget always displays [child].
78 | ///
79 | /// See also:
80 | ///
81 | /// * [MyDragTarget]
82 | /// * [LongPressMyDraggable]
83 | class MyDraggable extends StatefulWidget {
84 | /// Creates a widget that can be dragged to a [MyDragTarget].
85 | ///
86 | /// The [child] and [feedback] arguments must not be null. If
87 | /// [maxSimultaneousDrags] is non-null, it must be non-negative.
88 | const MyDraggable(
89 | {Key key,
90 | @required this.child,
91 | @required this.feedback,
92 | this.data,
93 | this.childWhenDragging,
94 | this.feedbackOffset: Offset.zero,
95 | this.dragAnchor: DragAnchor.child,
96 | this.affinity,
97 | this.maxSimultaneousDrags,
98 | this.onDragStarted,
99 | this.onMyDraggableCanceled,
100 | this.onDragCompleted,
101 | this.onMove})
102 | : assert(child != null),
103 | assert(feedback != null),
104 | assert(maxSimultaneousDrags == null || maxSimultaneousDrags >= 0),
105 | super(key: key);
106 |
107 | /// The data that will be dropped by this MyDraggable.
108 | final T data;
109 |
110 | /// The widget below this widget in the tree.
111 | ///
112 | /// This widget displays [child] when zero drags are under way. If
113 | /// [childWhenDragging] is non-null, this widget instead displays
114 | /// [childWhenDragging] when one or more drags are underway. Otherwise, this
115 | /// widget always displays [child].
116 | ///
117 | /// The [feedback] widget is shown under the pointer when a drag is under way.
118 | ///
119 | /// To limit the number of simultaneous drags on multitouch devices, see
120 | /// [maxSimultaneousDrags].
121 | ///
122 | /// {@macro flutter.widgets.child}
123 | final Widget child;
124 |
125 | /// The widget to display instead of [child] when one or more drags are under way.
126 | ///
127 | /// If this is null, then this widget will always display [child] (and so the
128 | /// drag source representation will not change while a drag is under
129 | /// way).
130 | ///
131 | /// The [feedback] widget is shown under the pointer when a drag is under way.
132 | ///
133 | /// To limit the number of simultaneous drags on multitouch devices, see
134 | /// [maxSimultaneousDrags].
135 | final Widget childWhenDragging;
136 |
137 | /// The widget to show under the pointer when a drag is under way.
138 | ///
139 | /// See [child] and [childWhenDragging] for information about what is shown
140 | /// at the location of the [MyDraggable] itself when a drag is under way.
141 | final Widget feedback;
142 |
143 | /// The feedbackOffset can be used to set the hit test target point for the
144 | /// purposes of finding a drag target. It is especially useful if the feedback
145 | /// is transformed compared to the child.
146 | final Offset feedbackOffset;
147 |
148 | /// Where this widget should be anchored during a drag.
149 | final DragAnchor dragAnchor;
150 |
151 | /// Controls how this widget competes with other gestures to initiate a drag.
152 | ///
153 | /// If affinity is null, this widget initiates a drag as soon as it recognizes
154 | /// a tap down gesture, regardless of any directionality. If affinity is
155 | /// horizontal (or vertical), then this widget will compete with other
156 | /// horizontal (or vertical, respectively) gestures.
157 | ///
158 | /// For example, if this widget is placed in a vertically scrolling region and
159 | /// has horizontal affinity, pointer motion in the vertical direction will
160 | /// result in a scroll and pointer motion in the horizontal direction will
161 | /// result in a drag. Conversely, if the widget has a null or vertical
162 | /// affinity, pointer motion in any direction will result in a drag rather
163 | /// than in a scroll because the MyDraggable widget, being the more specific
164 | /// widget, will out-compete the [Scrollable] for vertical gestures.
165 | final Axis affinity;
166 |
167 | /// How many simultaneous drags to support.
168 | ///
169 | /// When null, no limit is applied. Set this to 1 if you want to only allow
170 | /// the drag source to have one item dragged at a time. Set this to 0 if you
171 | /// want to prevent the MyDraggable from actually being dragged.
172 | ///
173 | /// If you set this property to 1, consider supplying an "empty" widget for
174 | /// [childWhenDragging] to create the illusion of actually moving [child].
175 | final int maxSimultaneousDrags;
176 |
177 | /// Called when the MyDraggable starts being dragged.
178 | final VoidCallback onDragStarted;
179 |
180 | /// Called when the MyDraggable is dropped without being accepted by a [MyDragTarget].
181 | ///
182 | /// This function might be called after this widget has been removed from the
183 | /// tree. For example, if a drag was in progress when this widget was removed
184 | /// from the tree and the drag ended up being canceled, this callback will
185 | /// still be called. For this reason, implementations of this callback might
186 | /// need to check [State.mounted] to check whether the state receiving the
187 | /// callback is still in the tree.
188 | final MyDraggableCanceledCallback onMyDraggableCanceled;
189 |
190 | /// Called when the MyDraggable is dropped and accepted by a [MyDragTarget].
191 | ///
192 | /// This function might be called after this widget has been removed from the
193 | /// tree. For example, if a drag was in progress when this widget was removed
194 | /// from the tree and the drag ended up completing, this callback will
195 | /// still be called. For this reason, implementations of this callback might
196 | /// need to check [State.mounted] to check whether the state receiving the
197 | /// callback is still in the tree.
198 | final VoidCallback onDragCompleted;
199 |
200 | final ValueChanged onMove;
201 |
202 | /// Creates a gesture recognizer that recognizes the start of the drag.
203 | ///
204 | /// Subclasses can override this function to customize when they start
205 | /// recognizing a drag.
206 | @protected
207 | GestureRecognizer createRecognizer(GestureMultiDragStartCallback onStart) {
208 | switch (affinity) {
209 | case Axis.horizontal:
210 | return new HorizontalMultiDragGestureRecognizer()..onStart = onStart;
211 | case Axis.vertical:
212 | return new VerticalMultiDragGestureRecognizer()..onStart = onStart;
213 | }
214 | return new ImmediateMultiDragGestureRecognizer()..onStart = onStart;
215 | }
216 |
217 | @override
218 | MyDraggableState createState() => new MyDraggableState();
219 | }
220 |
221 | /// Makes its child MyDraggable starting from long press.
222 | class LongPressMyDraggable extends MyDraggable {
223 | /// Creates a widget that can be dragged starting from long press.
224 | ///
225 | /// The [child] and [feedback] arguments must not be null. If
226 | /// [maxSimultaneousDrags] is non-null, it must be non-negative.
227 | const LongPressMyDraggable({
228 | Key key,
229 | @required Widget child,
230 | @required Widget feedback,
231 | T data,
232 | Widget childWhenDragging,
233 | Offset feedbackOffset: Offset.zero,
234 | DragAnchor dragAnchor: DragAnchor.child,
235 | int maxSimultaneousDrags,
236 | VoidCallback onDragStarted,
237 | MyDraggableCanceledCallback onMyDraggableCanceled,
238 | VoidCallback onDragCompleted,
239 | ValueChanged onMove,
240 | this.delay = const Duration(milliseconds: 500),
241 | }) : super(
242 | key: key,
243 | child: child,
244 | feedback: feedback,
245 | data: data,
246 | childWhenDragging: childWhenDragging,
247 | feedbackOffset: feedbackOffset,
248 | dragAnchor: dragAnchor,
249 | maxSimultaneousDrags: maxSimultaneousDrags,
250 | onDragStarted: onDragStarted,
251 | onMyDraggableCanceled: onMyDraggableCanceled,
252 | onDragCompleted: onDragCompleted,
253 | onMove: onMove);
254 |
255 | final Duration delay;
256 |
257 | @override
258 | DelayedMultiDragGestureRecognizer createRecognizer(
259 | GestureMultiDragStartCallback onStart) {
260 | return new DelayedMultiDragGestureRecognizer(delay: delay)
261 | ..onStart = (Offset position) {
262 | final Drag result = onStart(position);
263 | // if (result != null) HapticFeedback.selectionClick();
264 | return result;
265 | };
266 | }
267 | }
268 |
269 | class MyDraggableState extends State> {
270 | DragAvatar avatar;
271 | @override
272 | void initState() {
273 | super.initState();
274 | _recognizer = widget.createRecognizer(_startDrag);
275 | // _recognizer = new DelayedMultiDragGestureRecognizer()..onStart = (Offset pos){_startDrag(pos);};
276 | }
277 |
278 | @override
279 | void dispose() {
280 | _disposeRecognizerIfInactive();
281 | super.dispose();
282 | }
283 |
284 | // This gesture recognizer has an unusual lifetime. We want to support the use
285 | // case of removing the MyDraggable from the tree in the middle of a drag. That
286 | // means we need to keep this recognizer alive after this state object has
287 | // been disposed because it's the one listening to the pointer events that are
288 | // driving the drag.
289 | //
290 | // We achieve that by keeping count of the number of active drags and only
291 | // disposing the gesture recognizer after (a) this state object has been
292 | // disposed and (b) there are no more active drags.
293 | GestureRecognizer _recognizer;
294 | int _activeCount = 0;
295 |
296 | void _disposeRecognizerIfInactive() {
297 | if (_activeCount > 0) return;
298 | _recognizer.dispose();
299 | _recognizer = null;
300 | }
301 |
302 | void _routePointer(PointerEvent event) {
303 | if (widget.maxSimultaneousDrags != null &&
304 | _activeCount >= widget.maxSimultaneousDrags) return;
305 | _recognizer.addPointer(event);
306 | }
307 |
308 | DragAvatar _startDrag(Offset position) {
309 | if (widget.maxSimultaneousDrags != null &&
310 | _activeCount >= widget.maxSimultaneousDrags) return null;
311 | Offset dragStartPoint;
312 | switch (widget.dragAnchor) {
313 | case DragAnchor.child:
314 | final RenderBox renderObject = context.findRenderObject();
315 | dragStartPoint = renderObject.globalToLocal(position);
316 | break;
317 | case DragAnchor.pointer:
318 | dragStartPoint = Offset.zero;
319 | break;
320 | }
321 | setState(() {
322 | _activeCount += 1;
323 | });
324 | final DragAvatar avatar = new DragAvatar(
325 | overlayState: Overlay.of(context, debugRequiredFor: widget),
326 | data: widget.data,
327 | initialPosition: position,
328 | dragStartPoint: dragStartPoint,
329 | feedback: widget.feedback,
330 | feedbackOffset: widget.feedbackOffset,
331 | onMove: widget.onMove,
332 | onDragEnd: (Velocity velocity, Offset offset, bool wasAccepted) {
333 | if (mounted) {
334 | setState(() {
335 | _activeCount -= 1;
336 | });
337 | } else {
338 | _activeCount -= 1;
339 | _disposeRecognizerIfInactive();
340 | }
341 | if (wasAccepted && widget.onDragCompleted != null)
342 | widget.onDragCompleted();
343 | if (!wasAccepted && widget.onMyDraggableCanceled != null)
344 | widget.onMyDraggableCanceled(velocity, offset);
345 | });
346 | //TODO mine
347 | this.avatar = avatar;
348 | if (widget.onDragStarted != null) widget.onDragStarted();
349 | return avatar;
350 | }
351 |
352 | @override
353 | Widget build(BuildContext context) {
354 | assert(Overlay.of(context, debugRequiredFor: widget) != null);
355 | final bool canDrag = widget.maxSimultaneousDrags == null ||
356 | _activeCount < widget.maxSimultaneousDrags;
357 | final bool showChild =
358 | _activeCount == 0 || widget.childWhenDragging == null;
359 | return new Listener(
360 | onPointerDown: canDrag ? _routePointer : null,
361 | child: showChild ? widget.child : widget.childWhenDragging);
362 | }
363 | }
364 |
365 | /// A widget that receives data when a [MyDraggable] widget is dropped.
366 | ///
367 | /// When a MyDraggable is dragged on top of a drag target, the drag target is
368 | /// asked whether it will accept the data the MyDraggable is carrying. If the user
369 | /// does drop the MyDraggable on top of the drag target (and the drag target has
370 | /// indicated that it will accept the MyDraggable's data), then the drag target is
371 | /// asked to accept the MyDraggable's data.
372 | ///
373 | /// See also:
374 | ///
375 | /// * [MyDraggable]
376 | /// * [LongPressMyDraggable]
377 | class MyDragTarget extends StatefulWidget {
378 | /// Creates a widget that receives drags.
379 | ///
380 | /// The [builder] argument must not be null.
381 | const MyDragTarget({
382 | Key key,
383 | @required this.builder,
384 | this.onWillAccept,
385 | this.onAccept,
386 | this.onLeave,
387 | }) : super(key: key);
388 |
389 | /// Called to build the contents of this widget.
390 | ///
391 | /// The builder can build different widgets depending on what is being dragged
392 | /// into this drag target.
393 | final MyDragTargetBuilder builder;
394 |
395 | /// Called to determine whether this widget is interested in receiving a given
396 | /// piece of data being dragged over this drag target.
397 | ///
398 | /// Called when a piece of data enters the target. This will be followed by
399 | /// either [onAccept], if the data is dropped, or [onLeave], if the drag
400 | /// leaves the target.
401 | final MyDragTargetWillAccept onWillAccept;
402 |
403 | /// Called when an acceptable piece of data was dropped over this drag target.
404 | final MyDragTargetAccept onAccept;
405 |
406 | /// Called when a given piece of data being dragged over this target leaves
407 | /// the target.
408 | final MyDragTargetLeave onLeave;
409 |
410 | @override
411 | _MyDragTargetState createState() => new _MyDragTargetState();
412 | }
413 |
414 | List _mapAvatarsToData(List> avatars) {
415 | return avatars.map((DragAvatar avatar) => avatar.data).toList();
416 | }
417 |
418 | class _MyDragTargetState extends State> {
419 | final List> _candidateAvatars = >[];
420 | final List> _rejectedAvatars = >[];
421 |
422 | bool didEnter(DragAvatar avatar) {
423 | assert(!_candidateAvatars.contains(avatar));
424 | assert(!_rejectedAvatars.contains(avatar));
425 | if (avatar.data is T &&
426 | (widget.onWillAccept == null || widget.onWillAccept(avatar.data))) {
427 | setState(() {
428 | _candidateAvatars.add(avatar);
429 | });
430 | return true;
431 | }
432 | _rejectedAvatars.add(avatar);
433 | return false;
434 | }
435 |
436 | void didLeave(DragAvatar avatar) {
437 | assert(_candidateAvatars.contains(avatar) ||
438 | _rejectedAvatars.contains(avatar));
439 | if (!mounted) return;
440 | setState(() {
441 | _candidateAvatars.remove(avatar);
442 | _rejectedAvatars.remove(avatar);
443 | });
444 | if (widget.onLeave != null) widget.onLeave(avatar.data);
445 | }
446 |
447 | void didDrop(DragAvatar avatar) {
448 | assert(_candidateAvatars.contains(avatar));
449 | if (!mounted) return;
450 | setState(() {
451 | _candidateAvatars.remove(avatar);
452 | });
453 | if (widget.onAccept != null) widget.onAccept(avatar.data);
454 | }
455 |
456 | @override
457 | Widget build(BuildContext context) {
458 | assert(widget.builder != null);
459 | return new MetaData(
460 | metaData: this,
461 | behavior: HitTestBehavior.translucent,
462 | child: widget.builder(context, _mapAvatarsToData(_candidateAvatars),
463 | _mapAvatarsToData(_rejectedAvatars)));
464 | }
465 | }
466 |
467 | enum _DragEndKind { dropped, canceled }
468 | typedef void _OnDragEnd(Velocity velocity, Offset offset, bool wasAccepted);
469 |
470 | // The lifetime of this object is a little dubious right now. Specifically, it
471 | // lives as long as the pointer is down. Arguably it should self-immolate if the
472 | // overlay goes away. _MyDraggableState has some delicate logic to continue
473 | // eeding this object pointer events even after it has been disposed.
474 | class DragAvatar extends Drag {
475 | DragAvatar({
476 | @required this.overlayState,
477 | this.data,
478 | Offset initialPosition,
479 | this.dragStartPoint: Offset.zero,
480 | this.feedback,
481 | this.feedbackOffset: Offset.zero,
482 | this.onDragEnd,
483 | this.onMove,
484 | }) : assert(overlayState != null),
485 | assert(dragStartPoint != null),
486 | assert(feedbackOffset != null) {
487 | _entry = new OverlayEntry(builder: _build);
488 | overlayState.insert(_entry);
489 | _position = initialPosition;
490 | updateDrag(initialPosition);
491 | }
492 |
493 | final T data;
494 | final Offset dragStartPoint;
495 | final Widget feedback;
496 | final Offset feedbackOffset;
497 | final _OnDragEnd onDragEnd;
498 | final OverlayState overlayState;
499 |
500 | _MyDragTargetState _activeTarget;
501 | final List<_MyDragTargetState> _enteredTargets = <_MyDragTargetState>[];
502 | Offset _position;
503 | Offset _lastOffset;
504 | OverlayEntry _entry;
505 |
506 | final ValueChanged onMove;
507 |
508 | double startClamp = -1.0;
509 | double endClamp = -1.0;
510 |
511 | void updateZero() {
512 | updateDrag(_position);
513 | }
514 |
515 | @override
516 | void update(DragUpdateDetails details) {
517 | _position += details.delta;
518 | updateDrag(_position);
519 | }
520 |
521 | @override
522 | void end(DragEndDetails details) {
523 | finishDrag(_DragEndKind.dropped, details.velocity);
524 | }
525 |
526 | @override
527 | void cancel() {
528 | finishDrag(_DragEndKind.canceled);
529 | }
530 |
531 | void updateDrag(Offset globalPosition) {
532 | _lastOffset = globalPosition - dragStartPoint;
533 | _entry.markNeedsBuild();
534 |
535 | //TODO norbert it's here :)
536 | onMove(globalPosition);
537 | final HitTestResult result = new HitTestResult();
538 | WidgetsBinding.instance.hitTest(result, globalPosition + feedbackOffset);
539 |
540 | final List<_MyDragTargetState> targets =
541 | _getMyDragTargets(result.path).toList();
542 |
543 | bool listsMatch = false;
544 | if (targets.length >= _enteredTargets.length &&
545 | _enteredTargets.isNotEmpty) {
546 | listsMatch = true;
547 | final Iterator<_MyDragTargetState> iterator = targets.iterator;
548 | for (int i = 0; i < _enteredTargets.length; i += 1) {
549 | iterator.moveNext();
550 | if (iterator.current != _enteredTargets[i]) {
551 | listsMatch = false;
552 | break;
553 | }
554 | }
555 | }
556 |
557 | // If everything's the same, bail early.
558 | if (listsMatch) return;
559 |
560 | // Leave old targets.
561 | _leaveAllEntered();
562 |
563 | // Enter new targets.
564 | final _MyDragTargetState newTarget =
565 | targets.firstWhere((_MyDragTargetState target) {
566 | _enteredTargets.add(target);
567 | return target.didEnter(this);
568 | }, orElse: _null);
569 |
570 | _activeTarget = newTarget;
571 | }
572 |
573 | static Null _null() => null;
574 |
575 | Iterable<_MyDragTargetState> _getMyDragTargets(
576 | List path) sync* {
577 | // Look for the RenderBoxes that corresponds to the hit target (the hit target
578 | // widgets build RenderMetaData boxes for us for this purpose).
579 | for (HitTestEntry entry in path) {
580 | if (entry.target is RenderMetaData) {
581 | final RenderMetaData renderMetaData = entry.target;
582 | if (renderMetaData.metaData is _MyDragTargetState)
583 | yield renderMetaData.metaData;
584 | }
585 | }
586 | }
587 |
588 | void _leaveAllEntered() {
589 | for (int i = 0; i < _enteredTargets.length; i += 1)
590 | _enteredTargets[i].didLeave(this);
591 | _enteredTargets.clear();
592 | }
593 |
594 | void finishDrag(_DragEndKind endKind, [Velocity velocity]) {
595 | bool wasAccepted = false;
596 | if (endKind == _DragEndKind.dropped && _activeTarget != null) {
597 | _activeTarget.didDrop(this);
598 | wasAccepted = true;
599 | _enteredTargets.remove(_activeTarget);
600 | }
601 | _leaveAllEntered();
602 | _activeTarget = null;
603 | _entry.remove();
604 | _entry = null;
605 | // TODO(ianh): consider passing _entry as well so the client can perform an animation.
606 | if (onDragEnd != null)
607 | onDragEnd(velocity ?? Velocity.zero, _lastOffset, wasAccepted);
608 | }
609 |
610 | Widget _build(BuildContext context) {
611 | final RenderBox box = overlayState.context.findRenderObject();
612 | final Offset overlayTopLeft = box.localToGlobal(Offset.zero);
613 | return new Positioned(
614 | //left: _lastOffset.dx - overlayTopLeft.dx,
615 | left: 0.0,
616 | top: _lastOffset.dy - overlayTopLeft.dy,
617 | child: new IgnorePointer(child: feedback));
618 | }
619 | }
620 |
--------------------------------------------------------------------------------
/lib/tools.dart:
--------------------------------------------------------------------------------
1 | double absMinus(double a, double b) {
2 | double result = a - b;
3 | if (result < 0) {
4 | return -result;
5 | } else {
6 | return result;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://www.dartlang.org/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "2.0.8"
11 | boolean_selector:
12 | dependency: transitive
13 | description:
14 | name: boolean_selector
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "1.0.4"
18 | charcode:
19 | dependency: transitive
20 | description:
21 | name: charcode
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "1.1.2"
25 | collection:
26 | dependency: transitive
27 | description:
28 | name: collection
29 | url: "https://pub.dartlang.org"
30 | source: hosted
31 | version: "1.14.11"
32 | flutter:
33 | dependency: "direct main"
34 | description: flutter
35 | source: sdk
36 | version: "0.0.0"
37 | flutter_test:
38 | dependency: "direct dev"
39 | description: flutter
40 | source: sdk
41 | version: "0.0.0"
42 | matcher:
43 | dependency: transitive
44 | description:
45 | name: matcher
46 | url: "https://pub.dartlang.org"
47 | source: hosted
48 | version: "0.12.3+1"
49 | meta:
50 | dependency: transitive
51 | description:
52 | name: meta
53 | url: "https://pub.dartlang.org"
54 | source: hosted
55 | version: "1.1.6"
56 | path:
57 | dependency: transitive
58 | description:
59 | name: path
60 | url: "https://pub.dartlang.org"
61 | source: hosted
62 | version: "1.6.2"
63 | quiver:
64 | dependency: transitive
65 | description:
66 | name: quiver
67 | url: "https://pub.dartlang.org"
68 | source: hosted
69 | version: "2.0.1"
70 | sky_engine:
71 | dependency: transitive
72 | description: flutter
73 | source: sdk
74 | version: "0.0.99"
75 | source_span:
76 | dependency: transitive
77 | description:
78 | name: source_span
79 | url: "https://pub.dartlang.org"
80 | source: hosted
81 | version: "1.4.1"
82 | stack_trace:
83 | dependency: transitive
84 | description:
85 | name: stack_trace
86 | url: "https://pub.dartlang.org"
87 | source: hosted
88 | version: "1.9.3"
89 | stream_channel:
90 | dependency: transitive
91 | description:
92 | name: stream_channel
93 | url: "https://pub.dartlang.org"
94 | source: hosted
95 | version: "1.6.8"
96 | string_scanner:
97 | dependency: transitive
98 | description:
99 | name: string_scanner
100 | url: "https://pub.dartlang.org"
101 | source: hosted
102 | version: "1.0.4"
103 | term_glyph:
104 | dependency: transitive
105 | description:
106 | name: term_glyph
107 | url: "https://pub.dartlang.org"
108 | source: hosted
109 | version: "1.0.1"
110 | test_api:
111 | dependency: transitive
112 | description:
113 | name: test_api
114 | url: "https://pub.dartlang.org"
115 | source: hosted
116 | version: "0.2.1"
117 | typed_data:
118 | dependency: transitive
119 | description:
120 | name: typed_data
121 | url: "https://pub.dartlang.org"
122 | source: hosted
123 | version: "1.1.6"
124 | vector_math:
125 | dependency: transitive
126 | description:
127 | name: vector_math
128 | url: "https://pub.dartlang.org"
129 | source: hosted
130 | version: "2.0.8"
131 | sdks:
132 | dart: ">=2.0.0 <3.0.0"
133 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: draggable_flutter_list
2 | description: a flutter list view which can drag & move item to change order.
3 | version: 1.0.3
4 | author: Realank
5 | homepage: https://github.com/Realank/draggable_flutter_list
6 |
7 | environment:
8 | sdk: ">=2.0.0-dev.28.0 <3.0.0"
9 |
10 | dependencies:
11 | flutter:
12 | sdk: flutter
13 |
14 | dev_dependencies:
15 | flutter_test:
16 | sdk: flutter
17 |
18 | # For information on the generic Dart part of this file, see the
19 | # following page: https://www.dartlang.org/tools/pub/pubspec
20 |
21 | # The following section is specific to Flutter.
22 | flutter:
23 |
24 | # To add assets to your package, add an assets section, like this:
25 | # assets:
26 | # - images/a_dot_burr.jpeg
27 | # - images/a_dot_ham.jpeg
28 | #
29 | # For details regarding assets in packages, see
30 | # https://flutter.io/assets-and-images/#from-packages
31 | #
32 | # An image asset can refer to one or more resolution-specific "variants", see
33 | # https://flutter.io/assets-and-images/#resolution-aware.
34 |
35 | # To add custom fonts to your package, add a fonts section here,
36 | # in this "flutter" section. Each entry in this list should have a
37 | # "family" key with the font family name, and a "fonts" key with a
38 | # list giving the asset and other descriptors for the font. For
39 | # example:
40 | # fonts:
41 | # - family: Schyler
42 | # fonts:
43 | # - asset: fonts/Schyler-Regular.ttf
44 | # - asset: fonts/Schyler-Italic.ttf
45 | # style: italic
46 | # - family: Trajan Pro
47 | # fonts:
48 | # - asset: fonts/TrajanPro.ttf
49 | # - asset: fonts/TrajanPro_Bold.ttf
50 | # weight: 700
51 | #
52 | # For details regarding fonts in packages, see
53 | # https://flutter.io/custom-fonts/#from-packages
54 |
--------------------------------------------------------------------------------
/screenshot.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Realank/draggable_flutter_list/d91801cab7d398aff37af13a3dc207ddaa5f02c9/screenshot.jpg
--------------------------------------------------------------------------------
/test/draggable_flutter_list_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/gestures.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:draggable_flutter_list/draggable_flutter_list.dart';
5 | import 'package:flutter_test/flutter_test.dart';
6 |
7 | void main() {
8 | testSwap();
9 | }
10 |
11 | void testSwap() {
12 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
13 | List items = [
14 | '0',
15 | '1',
16 | '2',
17 | '3',
18 | '4',
19 | '5',
20 | '6',
21 | '7',
22 | '8',
23 | '9',
24 | '10',
25 | '11',
26 | '12',
27 | '13',
28 | '14',
29 | '15',
30 | ];
31 |
32 | double tileSize = 64.0;
33 |
34 | StatefulBuilder app = new StatefulBuilder(
35 | builder: (BuildContext context, StateSetter setState) {
36 | return new MaterialApp(
37 | home: new DragAndDropList(
38 | items.length,
39 | itemBuilder: (BuildContext context, index) {
40 | return new SizedBox(
41 | height: tileSize,
42 | child: new Card(
43 | child: new ListTile(
44 | title: new Text(items[index]),
45 | ),
46 | ),
47 | );
48 | },
49 | onDragFinish: (before, after) {
50 | setState(() {
51 | String data = items[before];
52 | items.removeAt(before);
53 | items.insert(after, data);
54 | });
55 | },
56 | canBeDraggedTo: (one, two) => true,
57 | ),
58 | );
59 | },
60 | );
61 | // Build our app and trigger a frame.
62 | await tester.pumpWidget(app);
63 |
64 | // Verify that our counter starts at 0.
65 | expect(find.text('0'), findsOneWidget);
66 | expect(find.text('1'), findsOneWidget);
67 | expect(find.text('2'), findsOneWidget);
68 | expect(find.text('3'), findsOneWidget);
69 | expect(find.text('4'), findsOneWidget);
70 | expect(find.text('5'), findsOneWidget);
71 | expect(find.text('6'), findsOneWidget);
72 | expect(find.text('7'), findsOneWidget);
73 | expect(find.text('8'), findsOneWidget);
74 | expect(find.text('16'), findsNothing);
75 |
76 | await longPressDrag(find.text('0'), tester, new Offset(0.0, tileSize * 5));
77 |
78 | print(items);
79 | expect(items[0], '1');
80 | expect(items[1], '2');
81 | expect(items[2], '3');
82 | expect(items[4], '5');
83 | expect(items[5], '0');
84 | expect(items[6], '6');
85 | expect(items[7], '7');
86 | expect(items[8], '8');
87 |
88 | await longPressDragOffset(
89 | new Offset(100.0, tileSize * 5), tester, new Offset(0.0, tileSize * 2));
90 | expect(items[0], '1');
91 | expect(items[1], '2');
92 | expect(items[2], '3');
93 | expect(items[3], '4');
94 | expect(items[4], '0');
95 | expect(items[5], '6');
96 | expect(items[6], '7');
97 | expect(items[7], '5');
98 | print(items);
99 |
100 | await longPressDragOffset(
101 | new Offset(100.0, tileSize * 6), tester, new Offset(0.0, tileSize * 2));
102 | expect(items[0], '1');
103 | expect(items[1], '2');
104 | expect(items[2], '3');
105 | expect(items[3], '4');
106 | expect(items[4], '0');
107 | expect(items[5], '7');
108 | expect(items[6], '5');
109 | expect(items[7], '6');
110 | print(items);
111 |
112 | await longPressDragOffset(
113 | new Offset(100.0, tileSize * 5), tester, new Offset(0.0, tileSize * 2));
114 | expect(items[0], '1');
115 | expect(items[1], '2');
116 | expect(items[2], '3');
117 | expect(items[3], '4');
118 | expect(items[4], '7');
119 | expect(items[5], '5');
120 | expect(items[6], '6');
121 | expect(items[7], '0');
122 | print(items);
123 | });
124 | }
125 |
126 | /// Dispatch a pointer down / pointer up sequence at the given location with
127 | /// a delay of [kLongPressTimeout] + [kPressTimeout] between the two events.
128 | Future longPressDrag(Finder finder, WidgetTester tester, Offset dragOffset) {
129 | Offset location = tester.getCenter(finder);
130 | return TestAsyncUtils.guard(() async {
131 | final TestGesture gesture = await tester.startGesture(location);
132 | await tester.pump(kLongPressTimeout + kPressTimeout);
133 | await gesture.moveBy(dragOffset);
134 | await tester.pump(kLongPressTimeout + kPressTimeout);
135 | await gesture.up();
136 | return null;
137 | });
138 | }
139 |
140 | /// Dispatch a pointer down / pointer up sequence at the given location with
141 | /// a delay of [kLongPressTimeout] + [kPressTimeout] between the two events.
142 | Future longPressDragOffset(Offset location, WidgetTester tester, Offset dragOffset) {
143 | return TestAsyncUtils.guard(() async {
144 | final TestGesture gesture = await tester.startGesture(location);
145 | await tester.pump(kLongPressTimeout + kPressTimeout);
146 | await gesture.moveBy(dragOffset, timeStamp: new Duration(seconds: 2));
147 | await tester.pump(kLongPressTimeout + kPressTimeout);
148 | await gesture.up();
149 | return null;
150 | });
151 | }
152 |
--------------------------------------------------------------------------------