Xamarin.Forms中如何从相册多选图片?MediaPlugin选择器不支持该功能
Got it, I’ve been in your exact situation before—MediaPlugin is fantastic for single-image picks, but it’s definitely lacking when you need to select multiple photos from the system gallery. Here are a few reliable solutions you can implement:
1. Build Platform-Specific Implementations
Since Xamarin.Forms doesn’t have a native multi-select gallery API, writing platform-specific code gives you full control over the process.
Android Implementation
Use an Intent to launch the system gallery with multi-select enabled, then handle the returned data:
// In your Android activity or custom renderer var galleryIntent = new Intent(Intent.ActionGetContent); galleryIntent.SetType("image/*"); galleryIntent.PutExtra(Intent.ExtraAllowMultiple, true); StartActivityForResult(galleryIntent, 1001); // 1001 is a custom request code
Process the selected images in OnActivityResult:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); if (requestCode == 1001 && resultCode == Result.Ok) { var selectedImagePaths = new List<string>(); if (data.ClipData != null) { for (int i = 0; i < data.ClipData.ItemCount; i++) { var imageUri = data.ClipData.GetItemAt(i).Uri; // Convert Uri to a usable file path var filePath = GetRealPathFromUri(imageUri); selectedImagePaths.Add(filePath); } } // Pass the list of paths back to your shared Xamarin.Forms code } } // Android-specific helper to get real file path from Uri private string GetRealPathFromUri(Android.Net.Uri uri) { string[] projection = { MediaStore.Images.Media.InterfaceConsts.Data }; var cursor = ContentResolver.Query(uri, projection, null, null, null); if (cursor == null) return null; int columnIndex = cursor.GetColumnIndexOrThrow(MediaStore.Images.Media.InterfaceConsts.Data); cursor.MoveToFirst(); string path = cursor.GetString(columnIndex); cursor.Close(); return path; }
iOS Implementation
Use UIImagePickerController with AllowsMultipleSelection enabled (supported on iOS 11+):
// In your iOS view controller or custom renderer var imagePicker = new UIImagePickerController(); imagePicker.SourceType = UIImagePickerControllerSourceType.PhotoLibrary; imagePicker.MediaTypes = UIImagePickerController.AvailableMediaTypes(UIImagePickerControllerSourceType.PhotoLibrary); imagePicker.AllowsMultipleSelection = true; imagePicker.Delegate = new MultiImagePickerDelegate(); // Present the picker to the user UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(imagePicker, true, null);
Handle selected images in a custom delegate:
public class MultiImagePickerDelegate : UIImagePickerControllerDelegate { public override void FinishedPickingMedia(UIImagePickerController picker, NSDictionary info) { var selectedImagePaths = new List<string>(); if (info.ContainsKey(UIImagePickerController.SelectedImages)) { var imageArray = info[UIImagePickerController.SelectedImages] as NSArray; foreach (var obj in imageArray) { var uiImage = obj as UIImage; // Save the image to a temporary path for shared code access var tempPath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.jpg"); using (var stream = File.OpenWrite(tempPath)) { uiImage.AsJPEG().AsStream().CopyTo(stream); } selectedImagePaths.Add(tempPath); } } // Pass paths back to shared code and dismiss the picker picker.DismissViewController(true, null); } }
2. Use a Third-Party NuGet Package
If you want to skip writing platform-specific code, use a pre-built package that handles multi-select out of the box:
- Look for packages like
Plugin.MultipleImagePicker(check NuGet for the latest stable version). These packages wrap native logic into a shared API:
// In your shared Xamarin.Forms code var pickerOptions = new MultipleImagePickerOptions { MaxImages = 10, // Set your desired maximum selection count Title = "Select Photos" }; var selectedImages = await CrossMultipleImagePicker.Current.PickImagesAsync(pickerOptions); foreach (var image in selectedImages) { // Access image properties like Path or ByteArray var imagePath = image.Path; }
3. Wrap in a Dependency Service
To keep your shared code clean, wrap platform-specific logic in a DependencyService:
- Define a shared interface:
public interface IMultiImagePicker { Task<List<string>> PickMultipleImagesAsync(); }
- Implement this interface in your Android and iOS projects using the code from section 1.
- Call it from your shared code:
var imagePaths = await DependencyService.Get<IMultiImagePicker>().PickMultipleImagesAsync();
Important Notes
- Permissions: Don’t forget to request necessary permissions:
- Android: Add
READ_EXTERNAL_STORAGE(Android 10 and below) orREAD_MEDIA_IMAGES(Android 11+) to yourAndroidManifest.xml. - iOS: Add
NSPhotoLibraryUsageDescriptionto yourInfo.plistexplaining why you need gallery access.
- Android: Add
- Image Handling: Selected images can be large—consider resizing or compressing them to avoid memory issues.
Hope one of these solutions works for you! Platform-specific code gives you full control, while third-party packages save you time. Let me know if you need help with any specific part.
内容的提问来源于stack exchange,提问作者Adit Kothari

