Flutter WeChat Assets Picker
An assets picker which looks like the one in WeChat, based on photo_manager
for asset implementation, extended_image
for image preview, provider
to help controlling the state of the picker.
Category
- Migration Guide
- Features
- Screenshots
- Preparing for use
- Flutter
- Android
- iOS
- Usage
- Simple usage
- Complete param usage
- Register assets change observe callback
- Frequent asked questions
- Build failed with
Unresolved reference: R
- How can I get path from the
AssetEntity
to integrate withFile
object, upload or edit? - How can I change the name of “Recent” or other entities name/properties?
- Create
AssetEntity
fromFile
orUint8List
(rawData) - Console warning ‘Failed to find GeneratedAppGlideModule’
- Disable
ACCESS_MEDIA_LOCATION
permission
- Build failed with
Migration Guide
See Migration Guide.
Features
- Fully implementable with delegates override
- 99% similar to WeChat style
- Adjustable performance according to parameters
- Image asset support
- HEIC/HEIF Image type support
- Video asset support
- Audio asset support
- Single asset mode
- i18n support
- RTL language support
- Special item builder (prepend/append) support
- Custom sort path delegate support
- Custom text delegate support
- Custom filter options support (
photo_manager
) - Fully customizable theme
- macOS support
Screenshots
READ THIS FIRST
Althought the package provide selection for assets, it still require users build their own methods to handle display/upload, etc. If you have any question about how to build it, please run the example or refer to photo_manager for API usage.
Preparing for use
Version constraints
Flutter SDK: >=2.0.0
.
If you got a resolve conflict
error when running flutter pub get
, please use dependency_overrides
to fix it. See here .
Flutter
Add wechat_assets_picker
to pubspec.yaml
dependencies.
dependencies: wechat_assets_picker: ^latest_version
Then import the package in your code:
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
Android
Required permissions: INTERNET
, READ_EXTERNAL_STORAGE
, WRITE_EXTERNAL_STORAGE
, ACCESS_MEDIA_LOCATION
. If you don’t need the ACCESS_MEDIA_LOCATION
permission, see Disable ACCESS_MEDIA_LOCATION
permission.
If you found some warning logs with Glide
appearing, then the main project needs an implementation of AppGlideModule
. See Generated API.
iOS
- Platform version has to be at least 9.0. Modify
ios/Podfile
and update accordingly.
platform :ios, '9.0'
- Add the following content to
info.plist
.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSPhotoLibraryUsageDescription</key>
<string>Replace with your permission description.</string>
macOS
- Platform version has to be at least 10.15. Modify
macos/Podfile
and update accordingly.
platform :osx, '10.15'
- Set the minimum deployment target to 10.15. Use XCode to open
macos/Runner.xcworkspace
.
3. Follow the iOS instructions and modify info.plist
accordingly.
Usage
Name | Type | Description | Default |
---|---|---|---|
selectedAssets | List<AssetEntity>? | Selected assets. Prevent duplicate selection. If you don’t need to prevent duplicate selection, just don’t pass it. | null |
maxAssets | int | Maximum asset that the picker can pick. | 9 |
pageSize | int? | Number of assets per page. Must be a multiple of gridCount . | 320 (80 * 4) |
gridThumbSize | int | Thumbnail size for the grid’s item. | 200 |
pathThumbSize | int | Thumbnail size for the path selector. | 80 |
previewThumbSize | List<int>? | Preview thumbnail size in the viewer. | null |
gridCount | int | Grid count in picker. | 4 |
requestType | RequestType | Request type for picker. | RequestType.image |
specialPickerType | SpacialPickerType? | Provides the option to integrate a custom picker type. | null |
themeColor | Color? | Main theme color for the picker. | Color(0xff00bc56) |
pickerTheme | ThemeData? | Theme data provider for the picker and the viewer. | null |
sortPathDelegate | SortPathDeleage? | Path entities sort delegate for the picker, sort paths as you want. | CommonSortPathDelegate |
textDelegate | AssetsPickerTextDelegate? | Text delegate for the picker, for customize the texts. | DefaultAssetsPickerTextDelegate() |
filterOptions | FilterOptionGroup? | Allow users to customize assets filter options. | null |
specialItemBuilder | WidgetBuilder? | The widget builder for the special item. | null |
specialItemPosition | SpecialItemPosition | Allow users set a special item in the picker with several positions. | SpecialItemPosition.none |
loadingIndicatorBuilder | IndicatorBuilder? | Indicates the loading status for the builder. | null |
allowSpecialItemWhenEmpty | bool | Whether the special item will display or not when assets is empty. | false |
selectPredicate | AssetSelectPredicate | Predicate whether an asset can be selected or unselected. | null |
routeCurve | Curve | The curve which the picker use to build page route transition. | Curves.easeIn |
routeDuration | Duration | The duration which the picker use to build page route transition. | const Duration(milliseconds: 500) |
Simple usage
final List<AssetEntity> assets = await AssetPicker.pickAssets(context);
Using custom delegate
final YourAssetPickerProvider provider = yourProvider; final CustomAssetPickerBuilderDelegate builder = yourBuilder(provider); final List<YourAssetEntity>? result = await AssetPicker.pickAssetsWithDelegate( context, provider: provider, delegate: builder, );
You can use the keepScrollOffset
feature only with the pickAssetsWithDelegate
method. See the Keep scroll offset
pick method in the example for how to implement it.
Detailed usage
TL;DR, we’ve put multiple common usage with the packages into the example.
Regular picking
You can both found List<PickMethod> pickMethods
in example/lib/pages/multi_assets_page.dart
and example/lib/pages/single_assets_page.dart
, 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.
Custom pickers
You can try custom pickers with the “Custom” page. We only defined a picker that integrates with Directory
and File
(completely out of the photo_manager
scope). You can submit PRs to create your own implementation if you found your implementation might be useful for others. See [Contribute custom implementations][lib/customs/CONTRIBUTING.md] for more details.
Display selected assets
The AssetEntityImageProvider
can display the thumb image of images & videos, and the original data of image. Use it like a common ImageProvider
.
Image(image: AssetEntityImageProvider(asset, isOriginal: false))
Check the example for how it displays.
Register assets change observe callback
AssetPicker.registerObserve(); // Register callback.
AssetPicker.unregisterObserve(); // Unregister callback.
Customize with your own type or UI
AssetPickerBuilderDelegate
, AssetPickerViewerBuilderDelegate
, AssetPickerProvider
and AssetPickerViewerProvider
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 Custom
page in the example which has an implementation based on <File, Directory>
types.
Frequently asked question
Build failed with Unresolved reference: R
e: <path>\photo_manager-x.y.z\android\src\main\kotlin\top\kikt\imagescanner\core\PhotoManagerDeleteManager.kt: (116, 36): Unresolved reference: R e: <path>\photo_manager-x.y.z\android\src\main\kotlin\top\kikt\imagescanner\core\PhotoManagerDeleteManager.kt: (119, 36): Unresolved reference: createTrashRequest e: <path>\photo_manager-x.y.z\android\src\main\kotlin\top\kikt\imagescanner\core\PhotoManagerPlugin.kt: (341, 84): Unresolved reference: R e: <path>\photo_manager-x.y.z\android\src\main\kotlin\top\kikt\imagescanner\core\utils\Android30DbUtils.kt: (34, 34): Unresolved reference: R e: <path>\photo_manager-x.y.z\android\src\main\kotlin\top\kikt\imagescanner\core\utils\IDBUtils.kt: (27, 67): Unresolved reference: R FAILURE: Build failed with an exception.
Run flutter clean
first.
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 entity.originFile
, if Uint8List
then entity.originBytes
.
If you still need path after requested the File
, get it through file.absolutePath
.
How can I change the name of “Recent” or other entities name/properties?
The path entity called “Recent”, brought by photo_manager
in the path entities list, includes all AssetEntity
on your device. “Recent” is a system named entity in most platforms. While we provided ability to customize the text delegate, the name/properties can only be updated with SortPathDelegate
. This is the only way that you have access to all path entities, or the only way that we exposed currently.
To change the name of the path entity, extend the CommonSortPathDelegate
with your own delegate, then write something like the code below:
/// Create your own sort path delegate. class CustomSortPathDelegate extends CommonSortPathDelegate { const CustomSortPathDelegate(); @override void sort(List<AssetPathEntity> list) { ///.../// // In here you can check every path entities if you want. // The only property we recommend to change is [name], // And we have no responsibility for issues caused by // other properties update. for (final AssetPathEntity entity in list) { // If the entity `isAll`, that's the "Recent" entity you want. if (entity.isAll) { entity.name = 'Whatever you want'; } } ///.../// } }
Pass the delegate through the static call method, then you will get a self-named path entity.
Create AssetEntity
from File
or Uint8List
(rawData)
In order to combine this package with camera shooting or something related, there’s a solution about how to create an AssetEntity
with File
or Uint8List
object.
final File file = your_file; // Your file object final Uint8List byteData = await file.readAsBytes(); // Convert to Uint8List final AssetEntity imageEntity = await PhotoManager.editor.saveImage(byteData); // Saved in the device then create an AssetEntity
If you don’t want to keep the asset in your device, just delete it after you complete with your process (upload, editing, etc).
final List<String> result = await PhotoManager.editor.deleteWithIds([entity.id]);
ref: flutter_photo_manager#insert-new-item
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 AppGlideModule
. See Android section for implementation.
Disable ACCESS_MEDIA_LOCATION
permission
Android contains ACCESS_MEDIA_LOCATION
permission by default. This permission is introduced in Android Q. If your app doesn’t need the permission, you need to add the following node to the AndroidManifest.xml
in your app:
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" tools:node="remove" />
Download Flutter WeChat Assets Picker app source code GitHub
https://github.com/fluttercandies/flutter_wechat_assets_picker
Provides the list of the opensource Flutter apps collection with GitHub repository.