wechat_assets_picker 8.1.4 wechat_assets_picker: ^8.1.4 copied to clipboard
An audio/video/image picker in pure Dart which is the same with WeChat, support multi picking, custom item and delegates override.
Flutter WeChat Assets Picker #
Language: English | 中文
An assets' picker (audio/video/image picker) based on the WeChat's UI, using photo_manager for asset implementation, extended_image for image preview, and provider to help control the state of the picker.
To take a photo or a video for assets, please check the detailed usage in the example, and head over to wechat_camera_picker.
Current WeChat version that UI based on: 8.x UI designs will be updated following the WeChat update in anytime.
Category 🗂 #
- Migration Guide
- Preparing for use
- Frequently asked question
Migration Guide ♻️ #
See Migration Guide.
Features ✨ #
- ♻️ Fully implementable with delegates override
- 💚 99% similar to WeChat style
- ⚡️ Adjustable performance according to parameters
- 📷 Image asset support
- 🔬 HEIF Image type support
- 🎥 Video asset support
- 🎶 Audio asset support
- ⚠️ Due to limitations on iOS/macOS, audio can only be fetched within the sandbox
- 1️⃣ Single asset mode
- 💱 i18n support
- ⏪ RTL language support
- ➕ Special item builder support
- 🗂 Custom sort path delegate support
- 📝 Custom text delegate support
- ⏳ Custom filter options support
- 🎏 Fully customizable theme
- 💻 macOS support
Screenshots 📸 #
READ THIS FIRST ‼️ #
The package works closely with the photo_manager plugin, and most behaviors are controlled by the plugin. When you have questions about related APIs and behaviors, check photo_manager's API docs for more details.
Most usages are detailed covered by the example. Please walk through the example carefully before you have any questions.
Preparing for use 🍭 #
Versions compatibility #
If you got a
resolve conflict error when running
flutter pub get,
dependency_overrides to fix it.
flutter pub add wechat_assets_picker,
pubspec.yaml dependencies manually.
dependencies: wechat_assets_picker: ^latest_version
Then import the package in your code:
If you found some warning logs with
then the main project needs an implementation of
See Generated API docs.
|Name||Required||Declared||Max API Level||Others|
|YES*||NO||N/A||Required when reading EXIF|
|YES*||YES||N/A||Required when reading images|
|YES*||YES||N/A||Required when reading videos|
|YES*||YES||N/A||Required when reading audios|
If you're targeting Android SDK 33+, and you don't need to load photos, videos or audios, consider removing relevant permission in your apps, more specifically:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.your.app"> <!-- Remove READ_MEDIA_IMAGES if you don't need to load photos. --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" tools:node="remove" /> <!-- Remove READ_MEDIA_VIDEO if you don't need to load videos. --> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" tools:node="remove" /> <!-- Remove READ_MEDIA_AUDIO if you don't need to load audios. --> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" tools:node="remove" /> </manifest>
- Platform version has to be at least 9.0.
ios/Podfileand update accordingly.
platform :ios, '9.0'
- Add the following content to
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict> <key>NSPhotoLibraryUsageDescription</key> <string>Replace with your permission description.</string>
- Platform version has to be at least 10.15.
macos/Podfileand update accordingly.
platform :osx, '10.15'
- Set the minimum deployment target to 10.15.
Use XCode to open
- Follow the iOS instructions and modify
Usage 📖 #
Simple usage #
final List<AssetEntity>? result = await AssetPicker.pickAssets(context);
AssetPickerConfig for more picking behaviors.
final List<AssetEntity>? result = await AssetPicker.pickAssets( context, pickerConfig: const AssetPickerConfig(), );
|selectedAssets||Selected assets. Prevent duplicate selection.|
|maxAssets||Maximum asset that the picker can pick.||9|
|pageSize||Number of assets per page. Must be a multiple of ||80|
|gridThumbnailSize||Thumbnail size for the grid's item.|
|pathThumbnailSize||Thumbnail size for the path selector.|
|previewThumbnailSize||Preview thumbnail size in the viewer.|
|requestType||Request type for picker.|
|specialPickerType||Provides the option to integrate a custom picker type.|
|keepScrollOffset||Whether the picker should save the scroll offset between pushes and pops.|
|sortPathDelegate||Path entities sort delegate for the picker, sort paths as you want.|
|sortPathsByModifiedDate||Whether to allow sort delegates to sort paths with |
|filterOptions||Allow users to customize assets filter options.|
|gridCount||Grid count in picker.||4|
|themeColor||Main theme color for the picker.|
|pickerTheme||Theme data provider for the picker and the viewer.|
|textDelegate||Text delegate for the picker, for customize the texts.|
|specialItemPosition||Allow users set a special item in the picker with several positions.|
|specialItemBuilder||The widget builder for the special item.|
|loadingIndicatorBuilder||Indicates the loading status for the builder.|
|selectPredicate||Predicate whether an asset can be selected or unselected.|
|shouldRevertGrid||Whether the assets grid should revert.|
|limitedPermissionOverlayPredicate||Predicate whether the limited permission overlay should be displayed.|
|pathNameBuilder||Build customized path name.|
Detailed usage #
TL;DR, we've put multiple common usage with the packages in the example.
When you're picking assets, the package will obtain the
BuildContext, and return the corresponding text delegate
of the current language.
Make sure you have a valid
Locale in your widget tree that can be accessed
BuildContext. Otherwise, the default Chinese delegate will be used.
Embedded text delegates languages are:
- 简体中文 (default)
- مة العربية
If you want to use a custom/fixed text delegate, pass it through the
Using custom delegate #
You can use the
only with the
Keep scroll offset pick method
in the example for how to implement it.
For more details about custom delegates,
head over to
You can both found
List<PickMethod> pickMethods in
which provide methods in multiple picking and single picking mode.
Assets will be stored temporary and displayed at the below of the page.
Multiple assets picking
The maximum assets limit is
9 in the multiple picking page,
and you can modify it as you wish.
Some methods can only work with multiple mode, such as "WeChat Moment".
Single asset picking
Only one and maximum to one asset can be picked at once.
You can try custom pickers with the "Custom" page.
We've defined a picker that integrates with
(completely out of the
and a picker with multiple tabs switching.
You can submit PRs to create your own implementation
if you found your implementation might be useful for others.
See Contribute custom implementations for more details.
Display selected assets #
AssetEntityImageProvider can display the thumb image
of images & videos, and the original data of image.
Use it like a common
/// AssetEntityImage AssetEntityImage(asset, isOriginal: false); /// AssetEntityImageProvider Image(image: AssetEntityImageProvider(asset, isOriginal: false));
Register assets change observe callback #
/// Register callback. AssetPicker.registerObserve(); /// Unregister callback. AssetPicker.unregisterObserve();
Customize with your own type or UI #
are all exposed and overridable.
You can extend them and use your own
type with generic type
<A: Asset, P: Path>,
then implement abstract methods. See the
in the example which has an implementation
<File, Directory> types.
Frequently asked question ❔ #
Execution failed for task ':photo_manager:compileDebugKotlin' #
See photo_manager#561 for more details.
How can I get path from the
AssetEntity to integrate with
File object, upload or edit? #
You don't need it (might be).
You can always request the
File object with
If you still need path after requested the
File, get it through
final File file = await entity.file; // Thumbnails or edited files. final File originFile = await entity.originFile; // Original files. final String path = file.path; final String originPath = originFile.path;
Uint8List (rawData) #
In order to combine this package with camera shooting or something related,
there's a solution about how to create an
final File file = your_file; // Your `File` object final String path = file.path; final AssetEntity fileEntity = await PhotoManager.editor.saveImageWithPath( path, title: basename(path), ); // Saved in the device then create an AssetEntity final Uint8List data = your_data; // Your `Uint8List` object final AssetEntity imageEntity = await PhotoManager.editor.saveImage( file.path, title: 'title_with_extension.jpg', ); // Saved in the device then create an AssetEntity
Notice: If you don't want to keep the file in your device,
File for operations as much as possible.
A deletion operation might call system popups with some OS:
final List<String> result = await PhotoManager.editor.deleteWithIds( <String>[entity.id], );
Glide warning 'Failed to find GeneratedAppGlideModule' #
W/Glide (21133): Failed to find GeneratedAppGlideModule. You should include an annotationProcessor compile dependency on com.github.bumptech.glide:compiler in you application ana a @GlideModule annotated AppGlideModule implementation or LibraryGlideModules will be silently ignored.
Glide needs annotation to keep singleton,
prevent conflict between instances and versions,
so while the photo manager uses
Glide to implement image features,
the project which import this should define its own
See Android section for implementation.
Contributors ✨ #
Many thanks to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcomed!!
Every aspect of IntelliJ IDEA has been designed to maximize developer productivity. Together, intelligent coding assistance and ergonomic design make development not only productive but also enjoyable.