Langue: anglais | 中文
Un sélecteur d'images (également avec des vidéos et des audios) pour des projets de flutter basés sur l'interface utilisateur de WeChat.
La version WECHAT actuelle sur laquelle l'interface utilisateur basée sur: 8.0.51 Les conceptions d'interface utilisateur seront mises à jour après la mise à jour de WeChat à tout moment.
Pour prendre une photo ou une vidéo pour les actifs, veuillez consulter l'utilisation détaillée de l'exemple et rendez-vous sur WeChat_Camera_Picker. Le package est une extension autonome qui peut être utilisée avec une combinaison.
Voir le guide de migration pour apprendre à migrer entre les changements de rupture.
Le package garantit uniquement de travailler sur la version stable de Flutter . Nous ne le mettrons pas à jour en temps réel pour s'aligner avec d'autres canaux de flottement.
| 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 vous obtenez une erreur resolve conflict lors de l'exécution flutter pub get , veuillez utiliser dependency_overrides pour le réparer.
Le forfait est construit à partir de ces merveilleux packages.
| Nom | Caractéristiques |
|---|---|
| Photo_Manager | Les abstractions de base et la gestion des actifs. |
| Extended_image | Aperçu des actifs avec des comportements attendus. |
| fournisseur | Aide à gérer l'état d'interaction du sélecteur. |
| vidéo_player | Joue des vidéos et des audios en conséquence. |
Leur implémentation doit être relativement stable dans le package. Si vous avez trouvé des problèmes liés à ce que vous utilisez le Picker, soumettez d'abord des problèmes à notre tracker de problèmes.
AssetEntity avec des données de formulairehttpdioRecent en autres)AssetEntity à partir de File ou Uint8List (rawdata)ThemeDataentity.file ou AssetEntityImage pour eux lors de l'affichage.| nom | pub | github |
|---|---|---|
| insta_assets_picker |
![]() | ![]() | ![]() |
|---|---|---|
![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
Soyez conscient des avis ci-dessous avant de commencer quoi que ce soit:
AssetEntityAssetPathEntityLorsque vous avez des questions sur les API et les comportements connexes, consultez les documents API de Photo_Manager pour plus de détails.
La plupart des usages sont détaillés par l'exemple. Veuillez suivre soigneusement l'exemple avant d'avoir des questions.
Exécutez flutter pub add wechat_assets_picker , ou ajoutez manuellement wechat_assets_picker à pubspec.yaml .
dependencies :
wechat_assets_picker : ^latest_versionLa dernière version stable est:
La dernière version Dev est:
Ensuite, importez le package dans votre code:
import 'package:wechat_assets_picker/wechat_assets_picker.dart' ; Lorsque vous utilisez le package, veuillez mettre à niveau targetSdkVersion et compileSdkVersion vers 33 . Sinon, aucun actif ne peut être récupéré sur Android 13.
| Nom | Requis | Déclaré | Niveau de l'API max | Autres |
|---|---|---|---|---|
READ_EXTERNAL_STORAGE | OUI | OUI | 32 | |
WRITE_EXTERNAL_STORAGE | NON | NON | 29 | |
ACCESS_MEDIA_LOCATION | OUI* | NON | N / A | Requis lors de la lecture de l'exif |
READ_MEDIA_IMAGES | OUI* | OUI | N / A | Requis lors de la lecture d'images |
READ_MEDIA_VIDEO | OUI* | OUI | N / A | Requis lors de la lecture de vidéos |
READ_MEDIA_AUDIO | OUI* | OUI | N / A | Requis lors de la lecture des audios |
Si vous ciblez Android SDK 33+ et vous n'avez pas besoin de charger des photos, des vidéos ou des audios, envisagez de déclarer uniquement l'autorisation pertinente dans vos applications, plus précisément:
< 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 et mettez à jour en conséquence. platform :ios, '11.0'
# si la ligne commence avec elle.Info.plist . <key>NSPhotoLibraryUsageDescription</key>
<string>Replace with your permission description.</string>
macos/Podfile et mettez à jour en conséquence. platform :osx , '10.15'# si la ligne commence avec elle.macos/Runner.xcworkspace .Info.plist en conséquence. Lorsque vous choisissez des actifs, le colis obtiendra le Locale? à partir de votre BuildContext et renvoyez le délégué texte correspondant de la langue actuelle. Assurez-vous d'avoir un Locale valide dans votre arborescence de widget qui est accessible à partir de BuildContext . Sinon, le délégué chinois par défaut sera utilisé.
Les délégués de texte intégrés sont:
Si vous souhaitez utiliser un délégué de texte personnalisé / fixe, passez-le via AssetPickerConfig.textDelegate .
final List < AssetEntity > ? result = await AssetPicker . pickAssets (context); Utilisez AssetPickerConfig pour plus de comportements de cueillette.
final List < AssetEntity > ? result = await AssetPicker . pickAssets (
context,
pickerConfig : const AssetPickerConfig (),
); Champs dans AssetPickerConfig :
| Nom | Taper | Description | Défaut |
|---|---|---|---|
| SelectedAssets | List<AssetEntity>? | Actifs sélectionnés. Empêchez la sélection en double. | null |
| maxassets | int | Actif maximum que le sélecteur peut choisir. | 9 |
| pages | int? | Nombre d'actifs par page. Doit être un multiple de gridCount . | 80 |
| gridthumbnailSize | ThumbnailSize | Taille de la vignette pour l'article de la grille. | ThumbnailSize.square(200) |
| PathThumbnail | ThumbnailSize | Taille de la vignette pour le sélecteur de chemin. | ThumbnailSize.square(80) |
| prévisualisation | ThumbnailSize? | Aperçu de la taille de la vignette dans le spectateur. | null |
| requête | RequestType | Type de demande pour Picker. | RequestType.common |
| SpecialPickerType | SpecialPickerType? | Fournit la possibilité d'intégrer un type de sélecteur personnalisé. | null |
| KeepScrolloffset | bool | Si le sélecteur doit enregistrer le décalage de défilement entre les poussées et les pops. | null |
| sortpathdelegate | SortPathDelegate<AssetPathEntity>? | Les entités de chemin de trier déléguées pour le sélecteur, les chemins de tri comme vous le souhaitez. | CommonSortPathDelegate |
| sortpathsbymodifiedDate | bool | Il faut permettre à trier les délégués de trier les chemins avec FilterOptionGroup.containsPathModified . | false |
| filtrier | PMFilter? | Permettez aux utilisateurs de personnaliser les options de filtre des actifs. | null |
| grille | int | Nombre de grille dans Picker. | 4 |
| themecolor | Color? | Couleur du thème principal pour le sélectionneur. | Color(0xff00bc56) |
| PickerTheme | ThemeData? | Fournisseur de données à thème pour le sélecteur et le spectateur. | null |
| textodélégate | AssetPickerTextDelegate? | Délégué de texte pour le sélecteur, pour personnaliser les textes. | AssetPickerTextDelegate() |
| disposition spéciale | SpecialItemPosition | Autoriser les utilisateurs à définir un élément spécial dans le sélecteur avec plusieurs positions. | SpecialItemPosition.none |
| spécialité | SpecialItemBuilder? | Le constructeur du widget pour l'article spécial. | null |
| ChargeingIndicatorbuilder | IndicatorBuilder? | Indique l'état de chargement du constructeur. | null |
| selectpredicate | AssetSelectPredicate | Prédisez si un actif peut être sélectionné ou non sélectionné. | null |
| devaitrevertgrid | bool? | Si la grille des actifs devrait revenir. | null |
| LimitedPermissionOverlayPredicate | LimitedPermissionOverlayPredicate? | Prédisez si la superposition d'autorisation limitée doit être affichée. | null |
| pathnamebuilder | PathNameBuilder<AssetPathEntity>? | Construisez le nom de chemin (album) personnalisé avec l'entité de chemin donné. | null |
| AssetsChangeCallback | AssetsChangeCallback<AssetPathEntity>? | Le rappel qui sera appelé lorsque le système informe les actifs. | null |
| AssetsChangeRefreshPredicate | AssetsChangeRefreshPredicate<AssetPathEntity>? | La façon dont les actifs changent doivent appeler l'appel avec l'appel donné et le chemin sélectionné actuel. | null |
| Soupchable de la vieille | bool | Si l'aperçu doit jouer automatiquement. | false |
maxAssets est égal à 1 (aka mode de sélection unique), utilisez SpecialPickerType.noPreview sélectionnera immédiatement Asset cliqué sur Asset (appuyé) par l'utilisateur et a été sauté.limitedPermissionOverlayPredicate Lives sans persévérance, si vous souhaitez ignorer l'aperçu limité après le redémarrage, vous devrez vous intégrer à vos propres méthodes de sauvegarde. Nous avons mis une utilisation commune multiple avec les packages dans l'exemple. Vous pouvez tous deux trouver List<PickMethod> pickMethods ici et ici, qui fournissent des méthodes en mode de sélection et de sélection unique. Les actifs seront stockés temporaires et affichés à la page ci-dessous.
L' AssetEntityImage et AssetEntityImageProvider peuvent afficher l'image du pouce des images et des vidéos et les données originales de l'image . Utilisez-le comme une Image commune et ImageProvider .
AssetEntityImage (asset, isOriginal : false );Ou:
Image (image : AssetEntityImageProvider (asset, isOriginal : false )); // Register callback.
AssetPicker . registerObserve ();
// Unregister callback.
AssetPicker . unregisterObserve ();AssetEntity avec des données de formulaire Il existe plusieurs façons de télécharger un AssetEntity avec des méthodes liées aux E / S. Sachez que les méthodes liées aux E / S consommeront les performances (généralement du temps et de la mémoire), elles ne doivent pas être appelées fréquemment.
http Package http : https://pub.dev/packages/http
Le package http utilise MultipartFile pour gérer les fichiers dans les demandes.
Pseudo Code:
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 Package dio : https://pub.dev/packages/dio
Le package dio utilise également MultipartFile pour gérer les fichiers dans les demandes.
Pseudo Code:
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 et AssetPickerViewerProvider sont tous exposés et remplacés. Vous pouvez les étendre et utiliser votre propre type avec un type générique <A: Asset, P: Path> , puis implémenter des méthodes abstraites.
Pour savoir comment personnaliser pleinement les thèmes, les widgets ou les dispositions. Découvrez comment personnaliser les délégués dans la page Pickers personnalisés dans l'exemple.
Vous pouvez soumettre PRS pour créer votre propre implémentation si vous avez trouvé que votre implémentation pourrait être utile pour les autres. Voir contribuer les implémentations personnalisées pour plus de détails.
Recent en autres) Recent est le nom de l'album Fix pour les All Assets sur Android puisque l'album All Assets n'est pas un réel album, il ne représente que tous les enregistrements de données multimédias.
Pour résoudre cela sur Android, utilisez pathNameBuilder , par exemple:
AssetPickerConfig (
pathNameBuilder : ( AssetPathEntity path) => switch (path) {
final p when p.isAll => '最近' ,
// You can apply similar conditions to other common paths.
_ => path.name,
},
) D'autres albums ou albums sur d'autres plateformes (iOS / MacOS) suivront la localisation du système configuré et les localisations prises en charge. pathNameBuilder est disponible pour tous les albums.
Voir Photo_Manager # 561 pour plus de détails.
AssetEntity à partir de File ou Uint8List (rawdata) Afin de combiner ce package avec la prise de vue de la caméra ou quelque chose de lié, il existe une solution sur la façon de créer une AssetEntity avec File ou un objet 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 Remarque: Si vous ne souhaitez pas conserver le fichier dans votre appareil, utilisez autant que possible File pour les opérations. La suppression d'une AssetEntity peut provoquer une émission de popups système:
final List < String > result = await PhotoManager .editor. deleteWithIds (
< String > [entity.id],
);Voir Photo_Manager # From-RAW-Data et Photo_Manager # Delete-entities pour plus de détails.
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 a besoin d'annotation pour garder Singleton, empêcher les conflits entre les instances et les versions, donc bien que le gestionnaire de photos utilise Glide pour implémenter les fonctionnalités de l'image, le projet qui importe cela devrait définir son propre AppGlideModule . Voir les documents API générés par Glide pour l'implémentation.
Un grand merci à ces gens merveilleux (clé emoji):
Alex Li ? ? ? ? ️️ compris? | Caijinglong ? | Marcel Schneider ? ? | ganlanshu0211 ? ? | Jasonhezz ? | Yaniv shaked ? ? ? | avi-yadav |
Letalus ? ? | mât ? | Nickolay Savchenko ? | Kosuke Saigusa ? | 三闻书店 | Didiosfaust ? | xiejie ? |
Ahmed Masoud ? | luomo-pro ️️ compris? | paigupai ? | Muhammad Taqi Abdul Aziz | 何锦余 ? | Leon Dudlik ? | Maël ? |
ddrop | Nguyen phuc loi ? | Cevheri ? | mirimhee ? | Amos ? | Dimil Kalathiya | Gasol Wu ? |
Ce projet suit les spécifications de tous les contributeurs. Contributions de toute nature bienvenue !!
Chaque aspect de l'idée Intellij a été conçu pour maximiser la productivité des développeurs. Ensemble, l'assistance de codage intelligente et la conception ergonomique rendent le développement non seulement productif mais aussi agréable.
Merci à JetBrains pour l'allocation de licences gratuites en open source pour des IDE tels que Intellij Idea.
