Skip to content

Commit

Permalink
allow multiple
Browse files Browse the repository at this point in the history
  • Loading branch information
tarrinneal committed May 23, 2023
1 parent 044e5d5 commit 3743257
Show file tree
Hide file tree
Showing 31 changed files with 533 additions and 167 deletions.
4 changes: 3 additions & 1 deletion packages/image_picker/image_picker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,10 @@ final XFile? galleryVideo =
final XFile? cameraVideo = await picker.pickVideo(source: ImageSource.camera);
// Pick multiple images.
final List<XFile> images = await picker.pickMultiImage();
// Pick singe image or video.
final XFile? media = await picker.pickMedia();
// Pick multiple images and videos.
final List<XFile> media = await picker.pickMedia();
final List<XFile> medias = await picker.pickMultipleMedia();
```

## Migrating to 0.8.2+
Expand Down
47 changes: 43 additions & 4 deletions packages/image_picker/image_picker/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class _MyHomePageState extends State<MyHomePage> {
final XFile? file = await _picker.pickVideo(
source: source, maxDuration: const Duration(seconds: 10));
await _playVideo(file);
} else if (isMultiImage) {
} else if (isMultiImage && !isMedia) {
await _displayPickImageDialog(context,
(double? maxWidth, double? maxHeight, int? quality) async {
try {
Expand All @@ -112,11 +112,11 @@ class _MyHomePageState extends State<MyHomePage> {
});
}
});
} else if (isMedia) {
} else if (isMedia && isMultiImage) {
await _displayPickImageDialog(context,
(double? maxWidth, double? maxHeight, int? quality) async {
try {
final List<XFile> pickedFileList = await _picker.pickMedia(
final List<XFile> pickedFileList = await _picker.pickMultipleMedia(
maxWidth: maxWidth,
maxHeight: maxHeight,
imageQuality: quality,
Expand All @@ -130,6 +130,28 @@ class _MyHomePageState extends State<MyHomePage> {
});
}
});
} else if (isMedia) {
await _displayPickImageDialog(context,
(double? maxWidth, double? maxHeight, int? quality) async {
try {
final List<XFile> pickedFileList = <XFile>[];
final XFile? media = await _picker.pickMedia(
maxWidth: maxWidth,
maxHeight: maxHeight,
imageQuality: quality,
);
if (media != null) {
pickedFileList.add(media);
setState(() {
_imageFileList = pickedFileList;
});
}
} catch (e) {
setState(() {
_pickImageError = e;
});
}
});
} else {
await _displayPickImageDialog(context,
(double? maxWidth, double? maxHeight, int? quality) async {
Expand Down Expand Up @@ -338,6 +360,23 @@ class _MyHomePageState extends State<MyHomePage> {
child: const Icon(Icons.photo),
),
),
Padding(
padding: const EdgeInsets.only(top: 16.0),
child: FloatingActionButton(
onPressed: () {
isVideo = false;
_onImageButtonPressed(
ImageSource.gallery,
context: context,
isMultiImage: true,
isMedia: true,
);
},
heroTag: 'multipleMedia',
tooltip: 'Pick Multiple Media from gallery',
child: const Icon(Icons.photo_library),
),
),
Padding(
padding: const EdgeInsets.only(top: 16.0),
child: FloatingActionButton(
Expand All @@ -350,7 +389,7 @@ class _MyHomePageState extends State<MyHomePage> {
);
},
heroTag: 'media',
tooltip: 'Pick Media from gallery',
tooltip: 'Pick Single Media from gallery',
child: const Icon(Icons.photo_library),
),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ Future<List<XFile?>> readmePickExample() async {
final XFile? cameraVideo = await picker.pickVideo(source: ImageSource.camera);
// Pick multiple images.
final List<XFile> images = await picker.pickMultiImage();
// Pick singe image or video.
final XFile? media = await picker.pickMedia();
// Pick multiple images and videos.
final List<XFile> media = await picker.pickMedia();
final List<XFile> medias = await picker.pickMultipleMedia();
// #enddocregion Pick

// Return everything for the sanity check test.
Expand All @@ -31,7 +33,8 @@ Future<List<XFile?>> readmePickExample() async {
galleryVideo,
cameraVideo,
if (images.isEmpty) null else images.first,
if (media.isEmpty) null else media.first,
media,
if (medias.isEmpty) null else medias.first,
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ class FakeImagePicker extends ImagePickerPlatform {

@override
Future<List<XFile>> getMedia({required MediaSelectionOptions options}) async {
return <XFile>[XFile('media')];
return options.allowMultiple
? <XFile>[XFile('media'), XFile('medias')]
: <XFile>[XFile('media')];
}

@override
Expand Down
51 changes: 40 additions & 11 deletions packages/image_picker/image_picker/lib/image_picker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -283,36 +283,65 @@ class ImagePicker {
);
}

/// Returns an [XFile] of the image or video that was picked.
/// The image or videos can only come from the gallery.
///
/// Where iOS supports HEIC images, Android 8 and below doesn't. Android 9 and
/// above only support HEIC images if used in addition to a size modification,
/// of which the usage is explained below.
///
/// In Android, the MainActivity can be destroyed for various reasons.
/// If that happens, the result will be lost in this call. You can then
/// call [getLostData] when your app relaunches to retrieve the lost data.
///
/// If no images or videos were picked, the return value is null.
Future<XFile?> pickMedia({
double? maxWidth,
double? maxHeight,
int? imageQuality,
bool requestFullMetadata = true,
}) async {
final List<XFile> listMedia = await platform.getMedia(
options: MediaSelectionOptions(
imageOptions: ImageOptions.createAndValidate(
maxHeight: maxHeight,
maxWidth: maxWidth,
imageQuality: imageQuality,
requestFullMetadata: requestFullMetadata,
),
allowMultiple: false,
),
);

return listMedia.isNotEmpty ? listMedia.first : null;
}

/// Returns a [List<XFile>] with the images and/or videos that were picked.
/// The images and videos come from the gallery.
///
/// Where iOS supports HEIC images, Android 8 and below doesn't. Android 9 and
/// above only support HEIC images if used in addition to a size modification,
/// of which the usage is explained below.
///
/// This method is only supported on Android API 19 and above.
/// It could possibly work on API 18 and below on some devices,
/// but this is not guaranteed.
///
/// In Android, the MainActivity can be destroyed for various reasons.
/// If that happens, the result will be lost in this call. You can then
/// call [getLostData] when your app relaunches to retrieve the lost data.
///
/// If no images or videos were picked, the return value is an empty list.
Future<List<XFile>> pickMedia({
List<MediaSelectionType>? types,
Future<List<XFile>> pickMultipleMedia({
double? maxWidth,
double? maxHeight,
int? imageQuality,
bool requestFullMetadata = true,
}) {
return platform.getMedia(
options: MediaSelectionOptions(
types: types,
maxHeight: maxHeight,
maxWidth: maxWidth,
imageQuality: imageQuality,
requestFullMetadata: requestFullMetadata,
imageOptions: ImageOptions.createAndValidate(
maxHeight: maxHeight,
maxWidth: maxWidth,
imageQuality: imageQuality,
requestFullMetadata: requestFullMetadata,
),
),
);
}
Expand Down
Loading

0 comments on commit 3743257

Please sign in to comment.