filepick
A WhatsApp & Telegram style media picker, attachment selector, image cropper, and upload progress ring for Flutter apps.
Features
- 📸 In-App Media Picker Sheet: Displays live camera tile first, recent photos/videos, album selection dropdown, limited media access management banner, and graceful system picker fallbacks.
- 📎 Attachment Selector: Clean sheet for picking photos, videos, and documents with file type enforcement.
- ✂️ Interactive Image Cropper: Pinch-to-zoom crop screen supporting 1:1 round avatars, 3:1 cover banners, or custom aspect ratios with automatic EXIF orientation fixing.
- ⭕ Upload Ring: Non-covering animated progress arc around circular avatars while media uploads are in progress.
- 🎨 Fully Themeable & Localizable: Adaptable colors via
FilePickTheme, custom text translations withFilePickStrings, and security guard hooks withFilePick.guard.
Installation
Add filepick to your pubspec.yaml:
dependencies:
filepick: ^1.0.0
Platform Setup
Android (android/app/src/main/AndroidManifest.xml)
Add permissions depending on your app's requirements:
<!-- Camera Access -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- Media Access for Android 13+ (API 33+) -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!-- Media Access for Android 12 and below -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
iOS (ios/Runner/Info.plist)
Add description keys for permissions required by photo picker and camera:
<key>NSCameraUsageDescription</key>
<string>Allow access to take photos and videos.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Allow access to select photos from your library.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Allow access to record video with audio.</string>
Usage Examples
1. Pick and Crop Profile Photo / Avatar
final CroppedImage? cropped = await pickAndCropImage(
context,
title: 'Crop Profile Photo',
aspectRatio: 1.0,
circle: true,
fileName: 'avatar.jpg',
);
if (cropped != null) {
// Access cropped.bytes (Uint8List) and cropped.fileName
}
2. Attach File / Photo / Video
final PlatformFile? file = await pickAttachment(
context,
extensions: ['jpg', 'png', 'pdf', 'mp4'],
title: 'Attach File',
);
if (file != null) {
// Access file.path, file.bytes, file.name, file.size
}
3. Display Upload Ring around Avatar
UploadRing(
active: isUploading,
strokeWidth: 4,
child: CircleAvatar(
radius: 40,
backgroundImage: NetworkImage(avatarUrl),
),
)
4. Customizing Theme & App Lock Guard
void main() {
// Guard against App Lock / lifecycle background re-locking during camera/gallery pick
FilePick.guard = <T>(action) => AppLockProvider.keepUnlockedDuring(action);
runApp(const MyApp());
}
// Custom Theme Extension
MaterialApp(
theme: ThemeData(
extensions: const [
FilePickTheme(
accentColor: Colors.deepOrange,
surfaceColor: Colors.white,
),
],
),
);
License
MIT License. See LICENSE for details.