An assets picker in WeChat style, support multi assets picking

  Flutter App, Packages, Picker, WeChat

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 with File object, upload or edit?
    • How can I change the name of “Recent” or other entities name/properties?
    • Create AssetEntity from File or Uint8List (rawData)
    • Console warning ‘Failed to find GeneratedAppGlideModule’
    • Disable ACCESS_MEDIA_LOCATION permission

Migration Guide recycle

See Migration Guide.

Features

  • recycle Fully implementable with delegates override
  • green_heart 99% similar to WeChat style
  • zap Adjustable performance according to parameters
  • camera Image asset support
    • microscope HEIC/HEIF Image type support
  • movie_camera Video asset support
  • notes Audio asset support
  • one Single asset mode
  • currency_exchange i18n support
    • rewind RTL language support
  • heavy_plus_sign Special item builder (prepend/append) support
  • card_index_dividers Custom sort path delegate support
  • memo Custom text delegate support
  • hourglass_flowing_sand Custom filter options support ( photo_manager )
  • flags Fully customizable theme
  • computer macOS support

Screenshots camera_flash

123
456
789
101012

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

The latest stable version is: 

The latest dev version is: 

Then import the package in your code:

import 'package:wechat_assets_picker/wechat_assets_picker.dart';

Android

Required permissions: INTERNETREAD_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGEACCESS_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

  1. Platform version has to be at least 9.0. Modify ios/Podfile and update accordingly.
platform :ios, '9.0'
  1. 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

  1. Platform version has to be at least 10.15. Modify macos/Podfile and update accordingly.
platform :osx, '10.15'
  1. Set the minimum deployment target to 10.15. Use XCode to open macos/Runner.xcworkspace .
step 1
step 2

3. Follow the iOS instructions and modify info.plist accordingly.

Usage 

NameTypeDescriptionDefault
selectedAssetsList<AssetEntity>?Selected assets. Prevent duplicate selection. If you don’t need to prevent duplicate selection, just don’t pass it.null
maxAssetsintMaximum asset that the picker can pick.9
pageSizeint?Number of assets per page. Must be a multiple of gridCount.320 (80 * 4)
gridThumbSizeintThumbnail size for the grid’s item.200
pathThumbSizeintThumbnail size for the path selector.80
previewThumbSizeList<int>?Preview thumbnail size in the viewer.null
gridCountintGrid count in picker.4
requestTypeRequestTypeRequest type for picker.RequestType.image
specialPickerTypeSpacialPickerType?Provides the option to integrate a custom picker type.null
themeColorColor?Main theme color for the picker.Color(0xff00bc56)
pickerThemeThemeData?Theme data provider for the picker and the viewer.null
sortPathDelegateSortPathDeleage?Path entities sort delegate for the picker, sort paths as you want.CommonSortPathDelegate
textDelegateAssetsPickerTextDelegate?Text delegate for the picker, for customize the texts.DefaultAssetsPickerTextDelegate()
filterOptionsFilterOptionGroup?Allow users to customize assets filter options.null
specialItemBuilderWidgetBuilder?The widget builder for the special item.null
specialItemPositionSpecialItemPositionAllow users set a special item in the picker with several positions.SpecialItemPosition.none
loadingIndicatorBuilderIndicatorBuilder?Indicates the loading status for the builder.null
allowSpecialItemWhenEmptyboolWhether the special item will display or not when assets is empty.false
selectPredicateAssetSelectPredicatePredicate whether an asset can be selected or unselected.null
routeCurveCurveThe curve which the picker use to build page route transition.Curves.easeIn
routeDurationDurationThe 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

AssetPickerBuilderDelegateAssetPickerViewerBuilderDelegateAssetPickerProvider 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 grey_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