Язык: английский | 中文
Выборщик изображений (также с видео и аудионами) для проектов Flutter на основе пользовательского интерфейса WeChat.
Текущая версия WeChat, в которой пользовательский интерфейс на основе: 8.0.51 дизайн пользовательского интерфейса, будет обновлена после обновления WeChat в любое время.
Чтобы сделать фотографию или видео для активов, проверьте подробное использование в примере и отправляйтесь в WeChat_Camera_Picker. Пакет представляет собой автономное расширение, которое можно использовать с комбинацией.
См. Руководство по миграции, чтобы узнать, как мигрировать между нарушениями изменений.
Пакет гарантирует, что только будет работать над стабильной версией Flutter . Мы не будем обновлять его в режиме реального времени, чтобы соответствовать другим каналам Flutter.
| 3.0 | 3.3 | 3.7 | 3.10 | 3.13 | 3.16 | |
|---|---|---|---|---|---|---|
| 8.9.0+ | ✅ | |||||
| 8.7.0+ | ✅ | |||||
| 8.5.0+ | ✅ | |||||
| 8.4.0+ | ✅ | |||||
| 8.0.0+ | ✅ | ✅ | ||||
| 7.3.0+ | ✅ | ✅ |
Если у вас есть ошибка resolve conflict при запуске flutter pub get , пожалуйста, используйте dependency_overrides , чтобы исправить это.
Пакет построен из этих замечательных пакетов.
| Имя | Функции |
|---|---|
| photo_manager | Основные абстракции и управление активами. |
| extended_image | Предварительный просмотр активов с ожидаемым поведением. |
| поставщик | Помогает управлять состоянием взаимодействия сборщика. |
| video_player | Играет в видео и аудиосистемы соответственно. |
Их реализация должна быть относительно стабильной в пакете. Если вы нашли какие -либо проблемы, связанные с ними при использовании Picker, сначала отправьте проблемы в нашу пробку.
AssetEntity с данными формыhttpdioRecent для других)AssetEntity из File или Uint8List (Rawdata)ThemeDataentity.file или AssetEntityImage для них при отображениях.| имя | паб | GitHub |
|---|---|---|
| insta_assets_picker |
![]() | ![]() | ![]() |
|---|---|---|
![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
Имейте в виду уведомления ниже, прежде чем что -либо начнете:
AssetEntityAssetPathEntityКогда у вас есть вопросы об связанных с ней API и поведении, проверьте документы API Photo_Manager для получения более подробной информации.
Большинство использования подробно охвачены примером. Пожалуйста, внимательно пройдите пример, прежде чем у вас возникнут вопросы.
Запустите flutter pub add wechat_assets_picker или добавить wechat_assets_picker в pubspec.yaml -зависимости вручную.
dependencies :
wechat_assets_picker : ^latest_versionПоследняя стабильная версия:
Последняя версия разработки :
Затем импортируйте пакет в свой код:
import 'package:wechat_assets_picker/wechat_assets_picker.dart' ; При использовании пакета, пожалуйста, обновите targetSdkVersion и compileSdkVersion до 33 . В противном случае, активы не могут быть извлечены на Android 13.
| Имя | Необходимый | Объявлен | Максимальный уровень API | Другие |
|---|---|---|---|---|
READ_EXTERNAL_STORAGE | ДА | ДА | 32 | |
WRITE_EXTERNAL_STORAGE | НЕТ | НЕТ | 29 | |
ACCESS_MEDIA_LOCATION | ДА* | НЕТ | N/a | Требуется при чтении Exif |
READ_MEDIA_IMAGES | ДА* | ДА | N/a | Требуется при чтении изображений |
READ_MEDIA_VIDEO | ДА* | ДА | N/a | Требуется при чтении видео |
READ_MEDIA_AUDIO | ДА* | ДА | N/a | Требуется при чтении звуков |
Если вы нацелены на Android SDK 33+, и вам не нужно загружать фотографии, видео или аудио, рассмотрите возможность объявить только соответствующее разрешение в ваших приложениях, более конкретно:
< manifest xmlns : android = " http://schemas.android.com/apk/res/android "
xmlns : tools = " http://schemas.android.com/tools "
package = " com.your.app " >
<!-- Requesting access to images and videos. -->
< uses-permission android : name = " android.permission.READ_MEDIA_IMAGES " />
< uses-permission android : name = " android.permission.READ_MEDIA_VIDEO " />
<!-- When your app has no need to access audio, remove it or comment it out. -->
<!-- <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> -->
</ manifest >ios/Podfile и обновите соответственно. platform :ios, '11.0'
# если линия начинается с нее.Info.plist . <key>NSPhotoLibraryUsageDescription</key>
<string>Replace with your permission description.</string>
macos/Podfile и обновить соответственно. platform :osx , '10.15'# если линия начинается с нее.macos/Runner.xcworkspace .Info.plist соответственно. Когда вы выбираете активы, пакет получит Locale? из вашего BuildContext и верните соответствующий текстовый делегат текущего языка. Убедитесь, что у вас есть действительный Locale в вашем дереве виджетов, к которому можно получить доступ от BuildContext . В противном случае будет использоваться китайский делегат по умолчанию.
Встроенные текстовые делегаты языки:
Если вы хотите использовать пользовательский/фиксированный текстовый делегат, передайте его через AssetPickerConfig.textDelegate .
final List < AssetEntity > ? result = await AssetPicker . pickAssets (context); Используйте AssetPickerConfig для большего количества поведения сбора.
final List < AssetEntity > ? result = await AssetPicker . pickAssets (
context,
pickerConfig : const AssetPickerConfig (),
); Поля в AssetPickerConfig :
| Имя | Тип | Описание | По умолчанию |
|---|---|---|---|
| SelectedAssets | List<AssetEntity>? | Выбранные активы. Предотвратить дублированный выбор. | null |
| Максассет | int | Максимальный актив, который может выбрать сборщик. | 9 |
| PageSize | int? | Количество активов на страницу. Должен быть кратный gridCount . | 80 |
| Gridthumbnailsize | ThumbnailSize | Размер миниатюры для предмета сетки. | ThumbnailSize.square(200) |
| PathThumbNailSize | ThumbnailSize | Размер миниатюры для селектора пути. | ThumbnailSize.square(80) |
| Previewthumbnailsize | ThumbnailSize? | Предварительный просмотр размера миниатюры в зрителе. | null |
| requestType | RequestType | Тип запроса для Picker. | RequestType.common |
| SpecialPickerType | SpecialPickerType? | Предоставляет возможность интегрировать пользовательский тип сборщика. | null |
| сохраняет Crolloffset | bool | Должен ли сборщик сохранить смещение прокрутки между толчками и всплыванием. | null |
| SortPathDelegate | SortPathDelegate<AssetPathEntity>? | Path Entines сортирует делегат для сборщика, сортируйте пути, как вы хотите. | CommonSortPathDelegate |
| SortPathsBymodifiedDate | bool | Разрешить ли сортировки делегатов сортировать пути с помощью FilterOptionGroup.containsPathModified . | false |
| Filteroptions | PMFilter? | Позвольте пользователям настраивать параметры фильтра активов. | null |
| сетка | int | Счет сетки в Picker. | 4 |
| теме | Color? | Основной цвет темы для сборщика. | Color(0xff00bc56) |
| PickerTheme | ThemeData? | Поставщик данных для пикора и зрителя. | null |
| TextDelegate | AssetPickerTextDelegate? | Текст делегат для сборщика, для настройки текстов. | AssetPickerTextDelegate() |
| Специальное управление | SpecialItemPosition | Позвольте пользователям установить специальный элемент в сборщике с несколькими позициями. | SpecialItemPosition.none |
| СПЕЦИАЛЬНЫЙ МУБОЛЕР | SpecialItemBuilder? | Строитель виджетов для специального предмета. | null |
| Загрузка | IndicatorBuilder? | Указывает состояние загрузки для строителя. | null |
| SELECTPREDICATE | AssetSelectPredicate | Предикат, можно ли выбрать актив или не выбрать. | null |
| должен | bool? | Должна ли сетка активов вернуться. | null |
| LimitedPermissionOverlayPredicate | LimitedPermissionOverlayPredicate? | Предикат, следует ли отображаться ограниченное наложение разрешения. | null |
| PathNameBuilder | PathNameBuilder<AssetPathEntity>? | Создайте индивидуальный путь (альбом) название с данным объектом Path. | null |
| AssetschangeCallback | AssetsChangeCallback<AssetPathEntity>? | Обратный вызов, который будет вызван, когда система уведомляет активы, меняются. | null |
| AssetSchangerEfreshPedicate | AssetsChangeRefreshPredicate<AssetPathEntity>? | Независимо от того, следует ли изменение активов вызовать обновление с данным вызовом и текущим выбранным путем. | null |
| должен бытьаутоплеипрев | bool | Должен ли предварительный просмотр автоматически играть. | false |
maxAssets равно 1 (он же один режим выбора), используйте SpecialPickerType.noPreview , немедленно выбрав Asset Clicked (нажатый) пользователем и выпущенный.limitedPermissionOverlayPredicate Lives без настойчивости, если вы хотите игнорировать ограниченный предварительный просмотр после перезапуска, вам необходимо интегрировать с вашими собственными методами сбережений. Мы поместили несколько общих использования с пакетами в примере. Вы можете найти List<PickMethod> pickMethods здесь и здесь, которые предоставляют методы в режиме нескольких выбора и отдельного сбора. Активы будут сохранены временно и отображаются на нижеприведенной странице.
AssetEntityImage и AssetEntityImageProvider могут отображать изображение большого пальца изображений и видео , а также исходные данные изображения . Используйте его как общее Image и ImageProvider .
AssetEntityImage (asset, isOriginal : false );Или:
Image (image : AssetEntityImageProvider (asset, isOriginal : false )); // Register callback.
AssetPicker . registerObserve ();
// Unregister callback.
AssetPicker . unregisterObserve ();AssetEntity с данными формы Существует несколько способов загрузки AssetEntity с помощью методов, связанных с вводом/выводом. Имейте в виду, что методы, связанные с вводом/выводом, будут потреблять производительность (обычно время и память), их нельзя вызывать часто.
http http package: https://pub.dev/packages/http
В пакете http используется MultipartFile для обработки файлов в запросах.
Псевдод:
import 'package:http/http.dart' as http;
Future < void > upload () async {
final entity = await obtainYourEntity ();
final uri = Uri . https ( 'example.com' , 'create' );
final request = http. MultipartRequest ( 'POST' , uri)
..fields[ 'test_field' ] = 'test_value'
..files. add ( await multipartFileFromAssetEntity (entity));
final response = await request. send ();
if (response.statusCode == 200 ) {
print ( 'Uploaded!' );
}
}
Future <http. MultipartFile > multipartFileFromAssetEntity ( AssetEntity entity) async {
http. MultipartFile mf;
// Using the file path.
final file = await entity.file;
if (file == null ) {
throw StateError ( 'Unable to obtain file of the entity ${ entity . id }.' );
}
mf = await http. MultipartFile . fromPath ( 'test_file' , file.path);
// Using the bytes.
final bytes = await entity.originBytes;
if (bytes == null ) {
throw StateError ( 'Unable to obtain bytes of the entity ${ entity . id }.' );
}
mf = http. MultipartFile . fromBytes ( 'test_file' , bytes);
return mf;
}dio dio Package: https://pub.dev/packages/dio
Пакет dio также использует MultipartFile для обработки файлов в запросах.
Псевдод:
import 'package:dio/dio.dart' as dio;
Future < void > upload () async {
final entity = await obtainYourEntity ();
final uri = Uri . https ( 'example.com' , 'create' );
final response = dio. Dio (). requestUri (
uri,
data : dio. FormData . fromMap ({
'test_field' : 'test_value' ,
'test_file' : await multipartFileFromAssetEntity (entity),
}),
);
print ( 'Uploaded!' );
}
Future <dio. MultipartFile > multipartFileFromAssetEntity ( AssetEntity entity) async {
dio. MultipartFile mf;
// Using the file path.
final file = await entity.file;
if (file == null ) {
throw StateError ( 'Unable to obtain file of the entity ${ entity . id }.' );
}
mf = await dio. MultipartFile . fromFile (file.path);
// Using the bytes.
final bytes = await entity.originBytes;
if (bytes == null ) {
throw StateError ( 'Unable to obtain bytes of the entity ${ entity . id }.' );
}
mf = dio. MultipartFile . fromBytes (bytes);
return mf;
} AssetPickerBuilderDelegate , AssetPickerViewerBuilderDelegate , AssetPickerProvider и AssetPickerViewerProvider - все это выставлены и переопределяются. Вы можете расширить их и использовать свой собственный тип с общим типом <A: Asset, P: Path> , затем реализовать абстрактные методы.
Чтобы узнать о том, как полностью настроить темы, виджеты или макеты. Посмотрите, как настраивать делегаты на странице Paster Fickers в примере.
Вы можете отправить PRS для создания собственной реализации, если обнаружите, что ваша реализация может быть полезна для других. См. Внесите вклад в пользовательские реализации для более подробной информации.
Recent для других) Recent - это имя альбома Fix для All Assets on Android, так как альбом All Assets 'не является реальным альбомом, он представляет только все записи данных медиа.
Чтобы решить это на Android, используйте, например, pathNameBuilder :
AssetPickerConfig (
pathNameBuilder : ( AssetPathEntity path) => switch (path) {
final p when p.isAll => '最近' ,
// You can apply similar conditions to other common paths.
_ => path.name,
},
) Другие альбомы или альбомы на других платформах (iOS/MacOS) будут следить за локализацией настроенной системы и поддерживаемых локализации. pathNameBuilder доступен для всех альбомов.
См. Photo_manager#561 для получения более подробной информации.
AssetEntity из File или Uint8List (Rawdata) Чтобы объединить этот пакет с съемкой камеры или чем -то связанным, есть решение о том, как создать AssetEntity с File или объектом Uint8List .
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 Примечание: если вы не хотите хранить файл в вашем устройстве, используйте File для операций как можно больше. Удаление AssetEntity может привести к тому, что всплывающие окно системы показывают:
final List < String > result = await PhotoManager .editor. deleteWithIds (
< String > [entity.id],
);См. Photo_Manager#от Raw-Data и Photo_Manager#Delete-Entities для получения более подробной информации.
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 требует аннотации, чтобы сохранить Синглтон, предотвратить конфликт между экземплярами и версиями, поэтому, хотя Photo Manager использует Glide для реализации функций изображения, проект, который импортирует, должен определять свой собственный AppGlideModule . См. Glide, сгенерированные DOCS API для реализации.
Большое спасибо этим замечательным людям (ключ смайликов):
Алекс Ли ? ? ? ? ️? | Caijinglong ? | Марсель Шнайдер ? ? | Ganlanshu0211 ? ? | Джейсонхез ? | Янив Шакен ? ? ? | Ави-Ядав |
Леталус ? ? | Greymag ? | Николая Савченко ? | Косуке Сайгуса ? | 三闻书店 | Didiosfaust ? | Xiejie ? |
Ахмед Масуд ? | Luomo-pro ️? | Пейгупай ? | Мухаммед Таки Абдул Азиз | 何锦余 ? | Леон Дудлик ? | Маэль ? |
DDDROP | Нгуен Фук Лои ? | Cevheri ? | Мирими ? | Амос ? | Димиль Калатия | Gasol Wu ? |
Этот проект следует за спецификацией всех контролей. Вклад любого рода приветствовался !!
Каждый аспект идеи IntelliJ был разработан, чтобы максимизировать производительность разработчиков. Вместе интеллектуальная помощь в кодировании и эргономичный дизайн делают разработку не только продуктивной, но и приятной.
Спасибо Jetbrains за выделение бесплатных лицензий с открытым исходным кодом для IDE, таких как IntelliJ Idea.
