wechat_assets_picker 8.1.4 icon indicating copy to clipboard operation
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 #

pub package pub package Build status CodeFactor GitHub license

Awesome Flutter GitHub stars GitHub forks FlutterCandies

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 โ™ป๏ธ #

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 ๐Ÿ“ธ #

123
456
789
101012

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 #

2.8.02.10.03.0.03.3.0
8.0.0+N/AN/Aโœ…โœ…
7.3.0+N/AN/Aโœ…โœ…
7.0.0+โœ…โœ…โŒโŒ
6.3.0+โœ…โœ…โŒโŒ

If you got a resolve conflict error when running flutter pub get, please use dependency_overrides to fix it.

Flutter #

Run flutter pub add wechat_assets_picker, or add wechat_assets_picker to pubspec.yaml dependencies manually.

dependencies:
  wechat_assets_picker: ^latest_version

The latest stable version is: pub package

The latest dev version is: pub package

Then import the package in your code:

import 'package:wechat_assets_picker/wechat_assets_picker.dart';

Android #

If you found some warning logs with Glide appearing, then the main project needs an implementation of AppGlideModule. See Generated API docs.

Permissions

NameRequiredDeclaredMax API LevelOthers
READ_EXTERNAL_STORAGEYESYES32
WRITE_EXTERNAL_STORAGENONO29
ACCESS_MEDIA_LOCATIONYES*NON/ARequired when reading EXIF
READ_MEDIA_IMAGESYES*YESN/ARequired when reading images
READ_MEDIA_VIDEOYES*YESN/ARequired when reading videos
READ_MEDIA_AUDIOYES*YESN/ARequired 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>

iOS #

  1. Platform version has to be at least 9.0. Modify ios/Podfile and update accordingly.
    platform :ios, '9.0'
    
  2. 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'
    
  2. Set the minimum deployment target to 10.15. Use XCode to open macos/Runner.xcworkspace .
  3. step 1
  4. step 2
  5. Follow the iOS instructions and modify info.plist accordingly.

Usage ๐Ÿ“– #

Simple usage #

final List<AssetEntity>? result = await AssetPicker.pickAssets(context);

Use AssetPickerConfig for more picking behaviors.

final List<AssetEntity>? result = await AssetPicker.pickAssets(
  context,
  pickerConfig: const AssetPickerConfig(),
);

Fields in AssetPickerConfig:

NameTypeDescriptionDefault
selectedAssetsList<AssetEntity>?Selected assets. Prevent duplicate selection.null
maxAssetsintMaximum asset that the picker can pick.9
pageSizeint?Number of assets per page. Must be a multiple of gridCount.80
gridThumbnailSizeThumbnailSizeThumbnail size for the grid's item.ThumbnailSize.square(200)
pathThumbnailSizeThumbnailSizeThumbnail size for the path selector.ThumbnailSize.square(80)
previewThumbnailSizeThumbnailSize?Preview thumbnail size in the viewer.null
requestTypeRequestTypeRequest type for picker.RequestType.common
specialPickerTypeSpecialPickerType?Provides the option to integrate a custom picker type.null
keepScrollOffsetboolWhether the picker should save the scroll offset between pushes and pops.null
sortPathDelegateSortPathDelegate<AssetPathEntity>?Path entities sort delegate for the picker, sort paths as you want.CommonSortPathDelegate
sortPathsByModifiedDateboolWhether to allow sort delegates to sort paths with FilterOptionGroup.containsPathModified.false
filterOptionsFilterOptionGroup?Allow users to customize assets filter options.null
gridCountintGrid count in picker.4
themeColorColor?Main theme color for the picker.Color(0xff00bc56)
pickerThemeThemeData?Theme data provider for the picker and the viewer.null
textDelegateAssetPickerTextDelegate?Text delegate for the picker, for customize the texts.AssetPickerTextDelegate()
specialItemPositionSpecialItemPositionAllow users set a special item in the picker with several positions.SpecialItemPosition.none
specialItemBuilderSpecialItemBuilder?The widget builder for the special item.null
loadingIndicatorBuilderIndicatorBuilder?Indicates the loading status for the builder.null
selectPredicateAssetSelectPredicatePredicate whether an asset can be selected or unselected.null
shouldRevertGridbool?Whether the assets grid should revert.null
limitedPermissionOverlayPredicateLimitedPermissionOverlayPredicate?Predicate whether the limited permission overlay should be displayed.null
pathNameBuilderPathNameBuilder<AssetPathEntity>?Build customized path name.null

Detailed usage #

TL;DR, we've put multiple common usage with the packages in the example.

Localizations #

When you're picking assets, the package will obtain the Locale? from your 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 from the BuildContext. Otherwise, the default Chinese delegate will be used.

Embedded text delegates languages are:

  • ็ฎ€ไฝ“ไธญๆ–‡ (default)
  • English
  • ื”ืขื‘ืจื™ืช
  • Deutsche
  • ะ›ะพะบะฐะปะธะทะฐั†ะธั
  • ๆ—ฅๆœฌ่ชž
  • ู…ุฉ ุงู„ุนุฑุจูŠุฉ
  • Dรฉlรฉguรฉ

If you want to use a custom/fixed text delegate, pass it through the AssetPickerConfig.textDelegate.

Using custom delegate #

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.

For more details about custom delegates, head over to example/lib/customs.

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've defined a picker that integrates with Directory and File (completely out of the photo_manager scope), 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 #

The AssetImage and AssetEntityImageProvider can display the thumb image of images & videos, and the original data of image. Use it like a common Image and ImageProvider.

/// 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 #

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 โ” #

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 entity.file or entity.originFile, and entity.originBytes for Uint8List.

If you still need path after requested the File, get it through file.path.

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;

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 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, use 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],
);

ref: 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.

Contributors โœจ #

Many thanks to these wonderful people (emoji key):

Alex Li
Alex Li

๐Ÿ’ป ๐ŸŽจ ๐Ÿ“– ๐Ÿ’ก ๐Ÿค” ๐Ÿšง ๐Ÿ’ฌ ๐Ÿ‘€
Caijinglong
Caijinglong

๐Ÿ’ก ๐Ÿค”
Marcel Schneider
Marcel Schneider

๐Ÿ› ๐Ÿ’ป ๐Ÿค”
ganlanshu0211
ganlanshu0211

๐Ÿ› ๐Ÿค”
JasonHezz
JasonHezz

๐Ÿ› ๐Ÿ’ป
Yaniv Shaked
Yaniv Shaked

๐ŸŒ ๐Ÿ’ป ๐Ÿ› ๐Ÿšง
avi-yadav
avi-yadav

๐Ÿ’ป
Letalus
Letalus

๐Ÿ› ๐ŸŒ
greymag
greymag

๐ŸŒ
Nickolay Savchenko
Nickolay Savchenko

๐ŸŽจ
Kosuke Saigusa
Kosuke Saigusa

๐ŸŒ
ไธ‰้—ปไนฆๅบ—
ไธ‰้—ปไนฆๅบ—

๐Ÿ“–
DidiosFaust
DidiosFaust

๐ŸŒ
xiejie
xiejie

๐Ÿ›
Ahmed Masoud
Ahmed Masoud

๐ŸŒ
luomo-pro
luomo-pro

๏ธ๏ธ๏ธ๏ธโ™ฟ๏ธ ๐Ÿ›
paigupai
paigupai

๐ŸŒ
Muhammad Taqi Abdul Aziz
Muhammad Taqi Abdul Aziz

๐Ÿ“–
ไฝ•้”ฆไฝ™
ไฝ•้”ฆไฝ™

๐Ÿ›
Leon Dudlik
Leon Dudlik

๐Ÿ›

This project follows the all-contributors specification. Contributions of any kind welcomed!!

Acknowledgement #

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.

Thanks to JetBrains for allocating free open-source licenses for IDEs such as IntelliJ IDEA.

428
likes
135
pub points
98%
popularity

Publisher

verified publisher iconfluttercandies.com

An audio/video/image picker in pure Dart which is the same with WeChat, support multi picking, custom item and delegates override.

Repository (GitHub)

Documentation

API reference

License

Icon for licenses.Apache-2.0 (LICENSE)

Dependencies

extended_image, flutter, photo_manager, provider, video_player

More

Packages that depend on wechat_assets_picker