Skip to content

Commit dc2f9b8

Browse files
committed
platform examples matter too
1 parent b7dee14 commit dc2f9b8

File tree

14 files changed

+678
-218
lines changed

14 files changed

+678
-218
lines changed

packages/image_picker/image_picker_android/android/gradle.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,3 @@
1212
# org.gradle.parallel=true
1313
#Fri Jan 27 08:52:19 CST 2023
1414
org.gradle.jvmargs=-Xmx1536M -Dkotlin.daemon.jvm.options\="-Xmx1536M"
15-
android.useAndroidX=true

packages/image_picker/image_picker_android/example/lib/main.dart

Lines changed: 120 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import 'package:flutter_driver/driver_extension.dart';
1414
import 'package:image_picker_android/image_picker_android.dart';
1515
import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';
1616
// #enddocregion photo-picker-example
17+
import 'package:mime/mime.dart';
1718
import 'package:video_player/video_player.dart';
1819

1920
void appMain() {
@@ -62,7 +63,7 @@ class _MyHomePageState extends State<MyHomePage> {
6263
}
6364

6465
dynamic _pickImageError;
65-
bool isVideo = false;
66+
bool _isVideo = false;
6667

6768
VideoPlayerController? _controller;
6869
VideoPlayerController? _toBeDisposed;
@@ -77,18 +78,10 @@ class _MyHomePageState extends State<MyHomePage> {
7778
if (file != null && mounted) {
7879
await _disposeVideoController();
7980
late VideoPlayerController controller;
80-
if (kIsWeb) {
81-
controller = VideoPlayerController.network(file.path);
82-
} else {
83-
controller = VideoPlayerController.file(File(file.path));
84-
}
81+
82+
controller = VideoPlayerController.file(File(file.path));
8583
_controller = controller;
86-
// In web, most browsers won't honor a programmatic call to .play
87-
// if the video has a sound track (and is not muted).
88-
// Mute the video so it auto-plays in web!
89-
// This is not needed if the call to .play is the result of user
90-
// interaction (clicking on a "play" button, for example).
91-
const double volume = kIsWeb ? 0.0 : 1.0;
84+
const double volume = 1.0;
9285
await controller.setVolume(volume);
9386
await controller.initialize();
9487
await controller.setLooping(true);
@@ -101,12 +94,13 @@ class _MyHomePageState extends State<MyHomePage> {
10194
ImageSource source, {
10295
required BuildContext context,
10396
bool isMultiImage = false,
97+
bool isMedia = false,
10498
}) async {
10599
if (_controller != null) {
106100
await _controller!.setVolume(0.0);
107101
}
108102
if (context.mounted) {
109-
if (isVideo) {
103+
if (_isVideo) {
110104
final XFile? file = await _picker.getVideo(
111105
source: source, maxDuration: const Duration(seconds: 10));
112106
if (file != null && context.mounted) {
@@ -117,15 +111,54 @@ class _MyHomePageState extends State<MyHomePage> {
117111
await _displayPickImageDialog(context,
118112
(double? maxWidth, double? maxHeight, int? quality) async {
119113
try {
120-
final List<XFile>? pickedFileList = await _picker.getMultiImage(
121-
maxWidth: maxWidth,
122-
maxHeight: maxHeight,
123-
imageQuality: quality,
124-
);
114+
final List<XFile>? pickedFileList = isMedia
115+
? await _picker.getMedia(
116+
options: MediaOptions(
117+
allowMultiple: isMultiImage,
118+
imageOptions: ImageOptions(
119+
maxWidth: maxWidth,
120+
maxHeight: maxHeight,
121+
imageQuality: quality,
122+
)),
123+
)
124+
: await _picker.getMultiImage(
125+
maxWidth: maxWidth,
126+
maxHeight: maxHeight,
127+
imageQuality: quality,
128+
);
125129
if (pickedFileList != null && context.mounted) {
126130
_showPickedSnackBar(context, pickedFileList);
127131
}
128-
setState(() => _mediaFileList = pickedFileList);
132+
setState(() {
133+
_mediaFileList = pickedFileList;
134+
});
135+
} catch (e) {
136+
setState(() {
137+
_pickImageError = e;
138+
});
139+
}
140+
});
141+
} else if (isMedia) {
142+
await _displayPickImageDialog(context,
143+
(double? maxWidth, double? maxHeight, int? quality) async {
144+
try {
145+
final List<XFile> pickedFileList = <XFile>[];
146+
final XFile? media = _firstOrNull(await _picker.getMedia(
147+
options: MediaOptions(
148+
allowMultiple: isMultiImage,
149+
imageOptions: ImageOptions(
150+
maxWidth: maxWidth,
151+
maxHeight: maxHeight,
152+
imageQuality: quality,
153+
)),
154+
));
155+
156+
if (media != null) {
157+
pickedFileList.add(media);
158+
setState(() {
159+
_mediaFileList = pickedFileList;
160+
});
161+
}
129162
} catch (e) {
130163
setState(() => _pickImageError = e);
131164
}
@@ -207,18 +240,25 @@ class _MyHomePageState extends State<MyHomePage> {
207240
key: UniqueKey(),
208241
itemBuilder: (BuildContext context, int index) {
209242
final XFile image = _mediaFileList![index];
243+
final String? mime = lookupMimeType(_mediaFileList![index].path);
210244
return Column(
211245
mainAxisSize: MainAxisSize.min,
212246
children: <Widget>[
213247
Text(image.name,
214248
key: const Key('image_picker_example_picked_image_name')),
215-
// Why network for web?
216-
// See https://pub.dev/packages/image_picker#getting-ready-for-the-web-platform
217249
Semantics(
218250
label: 'image_picker_example_picked_image',
219-
child: kIsWeb
220-
? Image.network(image.path)
221-
: Image.file(File(image.path)),
251+
child: mime == null || mime.startsWith('image/')
252+
? Image.file(
253+
File(_mediaFileList![index].path),
254+
errorBuilder: (BuildContext context, Object error,
255+
StackTrace? stackTrace) {
256+
return const Center(
257+
child:
258+
Text('This image type is not supported'));
259+
},
260+
)
261+
: _buildInlineVideoPlayer(index),
222262
),
223263
],
224264
);
@@ -239,8 +279,19 @@ class _MyHomePageState extends State<MyHomePage> {
239279
}
240280
}
241281

282+
Widget _buildInlineVideoPlayer(int index) {
283+
final VideoPlayerController controller =
284+
VideoPlayerController.file(File(_mediaFileList![index].path));
285+
const double volume = 1.0;
286+
controller.setVolume(volume);
287+
controller.initialize();
288+
controller.setLooping(true);
289+
controller.play();
290+
return Center(child: AspectRatioVideo(controller));
291+
}
292+
242293
Widget _handlePreview() {
243-
if (isVideo) {
294+
if (_isVideo) {
244295
return _previewVideo();
245296
} else {
246297
return _previewImages();
@@ -254,10 +305,10 @@ class _MyHomePageState extends State<MyHomePage> {
254305
}
255306
if (response.file != null) {
256307
if (response.type == RetrieveType.video) {
257-
isVideo = true;
308+
_isVideo = true;
258309
await _playVideo(response.file);
259310
} else {
260-
isVideo = false;
311+
_isVideo = false;
261312
setState(() {
262313
if (response.files == null) {
263314
_setImageFileListFromFile(response.file);
@@ -316,7 +367,7 @@ class _MyHomePageState extends State<MyHomePage> {
316367
child: FloatingActionButton(
317368
key: const Key('image_picker_example_from_gallery'),
318369
onPressed: () {
319-
isVideo = false;
370+
_isVideo = false;
320371
_onImageButtonPressed(ImageSource.gallery, context: context);
321372
},
322373
heroTag: 'image0',
@@ -328,7 +379,40 @@ class _MyHomePageState extends State<MyHomePage> {
328379
padding: const EdgeInsets.only(top: 16.0),
329380
child: FloatingActionButton(
330381
onPressed: () {
331-
isVideo = false;
382+
_isVideo = false;
383+
_onImageButtonPressed(
384+
ImageSource.gallery,
385+
context: context,
386+
isMultiImage: true,
387+
isMedia: true,
388+
);
389+
},
390+
heroTag: 'multipleMedia',
391+
tooltip: 'Pick Multiple Media from gallery',
392+
child: const Icon(Icons.photo_library),
393+
),
394+
),
395+
Padding(
396+
padding: const EdgeInsets.only(top: 16.0),
397+
child: FloatingActionButton(
398+
onPressed: () {
399+
_isVideo = false;
400+
_onImageButtonPressed(
401+
ImageSource.gallery,
402+
context: context,
403+
isMedia: true,
404+
);
405+
},
406+
heroTag: 'media',
407+
tooltip: 'Pick Single Media from gallery',
408+
child: const Icon(Icons.photo_library),
409+
),
410+
),
411+
Padding(
412+
padding: const EdgeInsets.only(top: 16.0),
413+
child: FloatingActionButton(
414+
onPressed: () {
415+
_isVideo = false;
332416
_onImageButtonPressed(
333417
ImageSource.gallery,
334418
context: context,
@@ -344,7 +428,7 @@ class _MyHomePageState extends State<MyHomePage> {
344428
padding: const EdgeInsets.only(top: 16.0),
345429
child: FloatingActionButton(
346430
onPressed: () {
347-
isVideo = false;
431+
_isVideo = false;
348432
_onImageButtonPressed(ImageSource.camera, context: context);
349433
},
350434
heroTag: 'image2',
@@ -357,7 +441,7 @@ class _MyHomePageState extends State<MyHomePage> {
357441
child: FloatingActionButton(
358442
backgroundColor: Colors.red,
359443
onPressed: () {
360-
isVideo = true;
444+
_isVideo = true;
361445
_onImageButtonPressed(ImageSource.gallery, context: context);
362446
},
363447
heroTag: 'video0',
@@ -370,7 +454,7 @@ class _MyHomePageState extends State<MyHomePage> {
370454
child: FloatingActionButton(
371455
backgroundColor: Colors.red,
372456
onPressed: () {
373-
isVideo = true;
457+
_isVideo = true;
374458
_onImageButtonPressed(ImageSource.camera, context: context);
375459
},
376460
heroTag: 'video1',
@@ -510,3 +594,7 @@ class AspectRatioVideoState extends State<AspectRatioVideo> {
510594
}
511595
}
512596
}
597+
598+
T? _firstOrNull<T>(List<T> list) {
599+
return list.isEmpty ? null : list.first;
600+
}

packages/image_picker/image_picker_android/example/pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ dependencies:
2020
# the parent directory to use the current plugin's version.
2121
path: ../
2222
image_picker_platform_interface: ^2.8.0
23+
mime: ^1.0.4
2324
video_player: ^2.1.4
2425

2526
dev_dependencies:

0 commit comments

Comments
 (0)