Idioma: inglés | 中文
Un selector de imágenes (también con videos y audios) para proyectos de Flutter basados en la interfaz de usuario de WeChat.
La versión actual de WeChat en la que se basa: 8.0.51 UI Designs se actualizará después de la actualización de WeChat en cualquier momento.
Para tomar una foto o un video de los activos, consulte el uso detallado del ejemplo y diríjase a WeChat_Camera_Picker. El paquete es una extensión independiente que se puede usar con combinación.
Consulte la Guía de migración para aprender a migrar entre los cambios de ruptura.
El paquete solo garantiza trabajar en la versión estable de Flutter . No lo actualizaremos en tiempo real para alinearse con otros canales de 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+ | ✅ | ✅ |
Si recibió un error resolve conflict al ejecutar flutter pub get , use dependency_overrides para solucionarlo.
El paquete está construido a partir de estos maravillosos paquetes.
| Nombre | Características |
|---|---|
| Photo_Manager | Las abstracciones básicas y la gestión para los activos. |
| extended_image | Vista previa de activos con comportamientos esperados. |
| proveedor | Ayuda a administrar el estado de interacción del selector. |
| video_player | Reproduce videos y audios correspondientemente. |
Su implementación debe ser relativamente estable en el paquete. Si ha encontrado algún problema relacionado con ellos al usar el selector, envíe primero los problemas a nuestro rastreador de problemas.
AssetEntity con un formulario de datoshttpdioRecent a otros)AssetEntity desde File o Uint8List (RawData)ThemeDataentity.file o AssetEntityImage para ellos cuando se muestra.| nombre | pub | github |
|---|---|---|
| insta_assets_picker |
![]() | ![]() | ![]() |
|---|---|---|
![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
Tenga en cuenta los avisos a continuación antes de comenzar algo:
AssetEntityAssetPathEntityCuando tenga preguntas sobre API y comportamientos relacionados, consulte los documentos de API de Photo_Manager para obtener más detalles.
La mayoría de los usos se detallan por el ejemplo. Por favor, atraviese el ejemplo cuidadosamente antes de tener alguna pregunta.
Ejecute flutter pub add wechat_assets_picker o agregue wechat_assets_picker a las dependencias pubspec.yaml manualmente.
dependencies :
wechat_assets_picker : ^latest_versionLa última versión estable es:
La última versión de desarrollo es:
Luego importe el paquete en su código:
import 'package:wechat_assets_picker/wechat_assets_picker.dart' ; Cuando use el paquete, actualice targetSdkVersion y compileSdkVersion a 33 . De lo contrario, no se pueden obtener activos en Android 13.
| Nombre | Requerido | Declarado | Nivel de API máximo | Otros |
|---|---|---|---|---|
READ_EXTERNAL_STORAGE | SÍ | SÍ | 32 | |
WRITE_EXTERNAL_STORAGE | NO | NO | 29 | |
ACCESS_MEDIA_LOCATION | SÍ* | NO | N / A | Requerido al leer exif |
READ_MEDIA_IMAGES | SÍ* | SÍ | N / A | Requerido al leer imágenes |
READ_MEDIA_VIDEO | SÍ* | SÍ | N / A | Requerido al leer videos |
READ_MEDIA_AUDIO | SÍ* | SÍ | N / A | Requerido al leer audios |
Si se dirige a Android SDK 33+, y no necesita cargar fotos, videos o audios, considere declarar solo un permiso relevante en sus aplicaciones, más específicamente:
< 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 y actualice en consecuencia. platform :ios, '11.0'
# si la línea comienza con él.Info.plist . <key>NSPhotoLibraryUsageDescription</key>
<string>Replace with your permission description.</string>
macos/Podfile y actualizar en consecuencia. platform :osx , '10.15'# si la línea comienza con él.macos/Runner.xcworkspace .Info.plist . Cuando elige activos, ¿el paquete obtendrá el Locale? desde su BuildContext y devuelve el delegado de texto correspondiente del idioma actual. Asegúrese de tener una Locale válida en su árbol de widget al que se pueda acceder desde BuildContext . De lo contrario, se utilizará el delegado chino predeterminado.
Los idiomas de los delegados de texto incrustados son:
Si desea usar un delegado de texto personalizado/fijo, pase a través del AssetPickerConfig.textDelegate .
final List < AssetEntity > ? result = await AssetPicker . pickAssets (context); Use AssetPickerConfig para más comportamientos de selección.
final List < AssetEntity > ? result = await AssetPicker . pickAssets (
context,
pickerConfig : const AssetPickerConfig (),
); Campos en AssetPickerConfig :
| Nombre | Tipo | Descripción | Por defecto |
|---|---|---|---|
| conjuntos de datos seleccionados | List<AssetEntity>? | Activos seleccionados. Evitar la selección duplicada. | null |
| maxassets | int | Activo máximo que el selector puede elegir. | 9 |
| pagarse | int? | Número de activos por página. Debe ser un múltiplo de gridCount . | 80 |
| plidthumbnailsize | ThumbnailSize | Tamaño de miniatura para el artículo de la cuadrícula. | ThumbnailSize.square(200) |
| raththumbnailsize | ThumbnailSize | Tamaño de miniatura para el selector de ruta. | ThumbnailSize.square(80) |
| View ViewThumbnailSize | ThumbnailSize? | Vista previa del tamaño de la miniatura en el espectador. | null |
| requesttype | RequestType | Tipo de solicitud para el selector. | RequestType.common |
| SpecialPickerType | SpecialPickerType? | Proporciona la opción de integrar un tipo de selección personalizado. | null |
| KeepScrolloffset | bool | Si el selector debe guardar el desplazamiento de desplazamiento entre Pushes y Pops. | null |
| sortPathDelegate | SortPathDelegate<AssetPathEntity>? | Las entidades de ruta clasifican el delegado para el selector, clasifique las rutas como desee. | CommonSortPathDelegate |
| sortpathsbymodifiedDate | bool | Si permitir que los delegados clasifiquen rutas con FilterOptionGroup.containsPathModified . | false |
| FilterOptions | PMFilter? | Permitir a los usuarios personalizar las opciones de filtro de activos. | null |
| cuenta de la cuadrícula | int | Cuenta de cuadrícula en el selector. | 4 |
| themecolor | Color? | Color del tema principal para el selector. | Color(0xff00bc56) |
| pickerteme | ThemeData? | Proveedor de datos de temas para el selector y el espectador. | null |
| textdelegate | AssetPickerTextDelegate? | Delegado de texto para el selector, para personalizar los textos. | AssetPickerTextDelegate() |
| especialización especial | SpecialItemPosition | Permitir que los usuarios establezcan un elemento especial en el selector con varias posiciones. | SpecialItemPosition.none |
| SpecialItembuilder | SpecialItemBuilder? | El constructor de widgets para el artículo especial. | null |
| loadingindicatorbuilder | IndicatorBuilder? | Indica el estado de carga para el constructor. | null |
| seleccionar impedICA | AssetSelectPredicate | Predica si un activo puede ser seleccionado o no seleccionado. | null |
| Debería revertir | bool? | Si la cuadrícula de activos debe revertir. | null |
| LimitedPermissionOverLayPredicate | LimitedPermissionOverlayPredicate? | Predica si se debe mostrar la superposición de permiso limitado. | null |
| ruta | PathNameBuilder<AssetPathEntity>? | Construya el nombre de la ruta personalizada (álbum) con la entidad de ruta dada. | null |
| Assetschangecallback | AssetsChangeCallback<AssetPathEntity>? | La devolución de llamada que se llamará cuando el sistema notifique a los activos cambia. | null |
| AssetsChangeFreshpredicate | AssetsChangeRefreshPredicate<AssetPathEntity>? | Si el cambio de activos debe actualizar con la llamada dada y la ruta actual seleccionada. | null |
| deber | bool | Si la vista previa debe reproducirse automáticamente. | false |
maxAssets sea igual a 1 (también conocido como modo de selección única), use SpecialPickerType.noPreview seleccionará inmediatamente el activo hecho (presionado) por el usuario y apareció.limitedPermissionOverlayPredicate vidas sin persistencia, si desea ignorar la vista previa limitada después del reinicio, deberá integrarse con sus propios métodos de ahorro. Hemos puesto múltiples uso común con los paquetes en el ejemplo. Ambos pueden encontrar List<PickMethod> pickMethods aquí y aquí, que proporcionan métodos en múltiples selección y modo de selección única. Los activos se almacenarán temporales y se mostrarán en la siguiente página.
El AssetEntityImage y AssetEntityImageProvider pueden mostrar la imagen del pulgar de imágenes y videos , y los datos originales de la imagen . Úselo como una Image común y ImageProvider .
AssetEntityImage (asset, isOriginal : false );O:
Image (image : AssetEntityImageProvider (asset, isOriginal : false )); // Register callback.
AssetPicker . registerObserve ();
// Unregister callback.
AssetPicker . unregisterObserve ();AssetEntity con un formulario de datos Hay múltiples formas de cargar una AssetEntity con métodos relacionados con E/S. Tenga en cuenta que los métodos relacionados con E/S consumirán el rendimiento (generalmente tiempo y memoria), no deben llamarse con frecuencia.
http paquete http : https://pub.dev/packages/http
El paquete http utiliza MultipartFile para manejar archivos en las solicitudes.
Pseudo Código:
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 Paquete dio : https://pub.dev/packages/dio
El paquete dio también usa MultipartFile para manejar archivos en las solicitudes.
Pseudo Código:
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 y AssetPickerViewerProvider están expuestos y anulables. Puede extenderlos y usar su propio tipo con el tipo genérico <A: Asset, P: Path> , luego implementar métodos abstractos.
Para saber cómo personalizar completamente temas, widgets o diseños. Consulte cómo personalizar los delegados en la página de seleccionadores personalizados en el ejemplo.
Puede enviar PRS para crear su propia implementación si descubre que su implementación podría ser útil para otros. Consulte Contribuir implementaciones personalizadas para obtener más detalles.
Recent a otros) Recent es el nombre del álbum Fix para todos los activos en Android ya que el álbum de todos los activos no es un álbum real, solo representa todos los registros de datos de medios.
Para resolver eso en Android, use pathNameBuilder , por ejemplo:
AssetPickerConfig (
pathNameBuilder : ( AssetPathEntity path) => switch (path) {
final p when p.isAll => '最近' ,
// You can apply similar conditions to other common paths.
_ => path.name,
},
) Otros álbumes o álbumes en otras plataformas (iOS/MacOS) seguirán la localización del sistema configurada y las localizaciones compatibles. pathNameBuilder está disponible para todos los álbumes.
Vea Photo_Manager#561 para más detalles.
AssetEntity desde File o Uint8List (RawData) Para combinar este paquete con disparos de cámara o algo relacionado, hay una solución sobre cómo crear una AssetEntity con File o el objeto 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 Aviso: si no desea mantener el archivo en su dispositivo, use File para las operaciones tanto como sea posible. Eliminar una AssetEntity puede causar ventanas emergentes del sistema:
final List < String > result = await PhotoManager .editor. deleteWithIds (
< String > [entity.id],
);Vea Photo_Manager#de Raw-Data y Photo_Manager#Eliminar las entidades para más detalles.
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 necesita anotación para mantener Singleton, evitar conflictos entre instancias y versiones, por lo que mientras el administrador de fotos usa Glide para implementar características de imagen, el proyecto que importa esto debería definir su propio AppGlideModule . Ver Docios API generados por Glide para la implementación.
Muchas gracias a estas maravillosas personas (Key Emoji):
Alex Li ? ? ? ? ️️ comenzó a ser? | Caijinglong ? | Marcel Schneider ? ? | ganlanshu0211 ? ? | Jasonhezz ? | Yaniv sacudido ? ? ? | avi-yadav |
Letalo ? ? | greymag ? | Nickolay Savchenko ? | Kosuke Saigusa ? | 三闻书店 | Didiosfausto ? | xiejie ? |
Ahmed Masoud ? | Luomo-Pro ️️ comenzó a ser? | paigupai ? | Muhammad taqi abdul aziz | 何锦余 ? | Leon Dudlik ? | Maël ? |
dddrop | Nguyen Phuc Loi ? | Cevheri ? | Mirimhee ? | Amos ? | Dimil Kalathiya | Gasol Wu ? |
Este proyecto sigue la especificación de todos los contribuyentes. ¡Contribuciones de cualquier tipo bienvenidas!
Todos los aspectos de la idea de IntelliJ han sido diseñados para maximizar la productividad del desarrollador. Juntos, la asistencia de codificación inteligente y el diseño ergonómico hacen que el desarrollo no solo sea productivo sino también agradable.
Gracias a JetBrains por asignar licencias gratuitas de código abierto para IDES como Idea IntelliJ.
