@@ -10,6 +10,7 @@ import 'dart:io';
10
10
import 'package:flutter/foundation.dart' ;
11
11
import 'package:flutter/material.dart' ;
12
12
import 'package:image_picker/image_picker.dart' ;
13
+ import 'package:mime/mime.dart' ;
13
14
import 'package:video_player/video_player.dart' ;
14
15
15
16
void main () {
@@ -38,10 +39,10 @@ class MyHomePage extends StatefulWidget {
38
39
}
39
40
40
41
class _MyHomePageState extends State <MyHomePage > {
41
- List <XFile >? _imageFileList ;
42
+ List <XFile >? _mediaFileList ;
42
43
43
44
void _setImageFileListFromFile (XFile ? value) {
44
- _imageFileList = value == null ? null : < XFile > [value];
45
+ _mediaFileList = value == null ? null : < XFile > [value];
45
46
}
46
47
47
48
dynamic _pickImageError;
@@ -80,8 +81,12 @@ class _MyHomePageState extends State<MyHomePage> {
80
81
}
81
82
}
82
83
83
- Future <void > _onImageButtonPressed (ImageSource source,
84
- {required BuildContext context, bool isMultiImage = false }) async {
84
+ Future <void > _onImageButtonPressed (
85
+ ImageSource source, {
86
+ required BuildContext context,
87
+ bool isMultiImage = false ,
88
+ bool isMedia = false ,
89
+ }) async {
85
90
if (_controller != null ) {
86
91
await _controller! .setVolume (0.0 );
87
92
}
@@ -94,14 +99,42 @@ class _MyHomePageState extends State<MyHomePage> {
94
99
await _displayPickImageDialog (context,
95
100
(double ? maxWidth, double ? maxHeight, int ? quality) async {
96
101
try {
97
- final List <XFile > pickedFileList = await _picker.pickMultiImage (
102
+ final List <XFile > pickedFileList = isMedia
103
+ ? await _picker.pickMultipleMedia (
104
+ maxWidth: maxWidth,
105
+ maxHeight: maxHeight,
106
+ imageQuality: quality,
107
+ )
108
+ : await _picker.pickMultiImage (
109
+ maxWidth: maxWidth,
110
+ maxHeight: maxHeight,
111
+ imageQuality: quality,
112
+ );
113
+ setState (() {
114
+ _mediaFileList = pickedFileList;
115
+ });
116
+ } catch (e) {
117
+ setState (() {
118
+ _pickImageError = e;
119
+ });
120
+ }
121
+ });
122
+ } else if (isMedia) {
123
+ await _displayPickImageDialog (context,
124
+ (double ? maxWidth, double ? maxHeight, int ? quality) async {
125
+ try {
126
+ final List <XFile > pickedFileList = < XFile > [];
127
+ final XFile ? media = await _picker.pickMedia (
98
128
maxWidth: maxWidth,
99
129
maxHeight: maxHeight,
100
130
imageQuality: quality,
101
131
);
102
- setState (() {
103
- _imageFileList = pickedFileList;
104
- });
132
+ if (media != null ) {
133
+ pickedFileList.add (media);
134
+ setState (() {
135
+ _mediaFileList = pickedFileList;
136
+ });
137
+ }
105
138
} catch (e) {
106
139
setState (() {
107
140
_pickImageError = e;
@@ -179,28 +212,34 @@ class _MyHomePageState extends State<MyHomePage> {
179
212
if (retrieveError != null ) {
180
213
return retrieveError;
181
214
}
182
- if (_imageFileList != null ) {
215
+ if (_mediaFileList != null ) {
183
216
return Semantics (
184
217
label: 'image_picker_example_picked_images' ,
185
218
child: ListView .builder (
186
219
key: UniqueKey (),
187
220
itemBuilder: (BuildContext context, int index) {
221
+ final String ? mime = lookupMimeType (_mediaFileList! [index].path);
222
+
188
223
// Why network for web?
189
224
// See https://pub.dev/packages/image_picker_for_web#limitations-on-the-web-platform
190
225
return Semantics (
191
226
label: 'image_picker_example_picked_image' ,
192
227
child: kIsWeb
193
- ? Image .network (_imageFileList! [index].path)
194
- : Image .file (
195
- File (_imageFileList! [index].path),
196
- errorBuilder: (BuildContext context, Object error,
197
- StackTrace ? stackTrace) =>
198
- const Center (
199
- child: Text ('This image type is not supported' )),
200
- ),
228
+ ? Image .network (_mediaFileList! [index].path)
229
+ : (mime == null || mime.startsWith ('image/' )
230
+ ? Image .file (
231
+ File (_mediaFileList! [index].path),
232
+ errorBuilder: (BuildContext context, Object error,
233
+ StackTrace ? stackTrace) {
234
+ return const Center (
235
+ child:
236
+ Text ('This image type is not supported' ));
237
+ },
238
+ )
239
+ : _buildInlineVideoPlayer (index)),
201
240
);
202
241
},
203
- itemCount: _imageFileList ! .length,
242
+ itemCount: _mediaFileList ! .length,
204
243
),
205
244
);
206
245
} else if (_pickImageError != null ) {
@@ -216,6 +255,17 @@ class _MyHomePageState extends State<MyHomePage> {
216
255
}
217
256
}
218
257
258
+ Widget _buildInlineVideoPlayer (int index) {
259
+ final VideoPlayerController controller =
260
+ VideoPlayerController .file (File (_mediaFileList! [index].path));
261
+ const double volume = kIsWeb ? 0.0 : 1.0 ;
262
+ controller.setVolume (volume);
263
+ controller.initialize ();
264
+ controller.setLooping (true );
265
+ controller.play ();
266
+ return Center (child: AspectRatioVideo (controller));
267
+ }
268
+
219
269
Widget _handlePreview () {
220
270
if (isVideo) {
221
271
return _previewVideo ();
@@ -239,7 +289,7 @@ class _MyHomePageState extends State<MyHomePage> {
239
289
if (response.files == null ) {
240
290
_setImageFileListFromFile (response.file);
241
291
} else {
242
- _imageFileList = response.files;
292
+ _mediaFileList = response.files;
243
293
}
244
294
});
245
295
}
@@ -300,6 +350,39 @@ class _MyHomePageState extends State<MyHomePage> {
300
350
child: const Icon (Icons .photo),
301
351
),
302
352
),
353
+ Padding (
354
+ padding: const EdgeInsets .only (top: 16.0 ),
355
+ child: FloatingActionButton (
356
+ onPressed: () {
357
+ isVideo = false ;
358
+ _onImageButtonPressed (
359
+ ImageSource .gallery,
360
+ context: context,
361
+ isMultiImage: true ,
362
+ isMedia: true ,
363
+ );
364
+ },
365
+ heroTag: 'multipleMedia' ,
366
+ tooltip: 'Pick Multiple Media from gallery' ,
367
+ child: const Icon (Icons .photo_library),
368
+ ),
369
+ ),
370
+ Padding (
371
+ padding: const EdgeInsets .only (top: 16.0 ),
372
+ child: FloatingActionButton (
373
+ onPressed: () {
374
+ isVideo = false ;
375
+ _onImageButtonPressed (
376
+ ImageSource .gallery,
377
+ context: context,
378
+ isMedia: true ,
379
+ );
380
+ },
381
+ heroTag: 'media' ,
382
+ tooltip: 'Pick Single Media from gallery' ,
383
+ child: const Icon (Icons .photo_library),
384
+ ),
385
+ ),
303
386
Padding (
304
387
padding: const EdgeInsets .only (top: 16.0 ),
305
388
child: FloatingActionButton (
0 commit comments