{"id":13551224,"url":"https://github.com/fluttercandies/flutter_wechat_assets_picker","last_synced_at":"2025-05-13T23:07:56.779Z","repository":{"id":37560971,"uuid":"250156789","full_name":"fluttercandies/flutter_wechat_assets_picker","owner":"fluttercandies","description":"An image picker (also with video and audio) for Flutter projects based on the WeChat's UI.","archived":false,"fork":false,"pushed_at":"2025-04-23T09:06:44.000Z","size":30088,"stargazers_count":1572,"open_issues_count":9,"forks_count":467,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-04-23T09:40:44.440Z","etag":null,"topics":["android","flutter","ios","macos","mobile","multiple-assets","picker","video","wechat"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/wechat_assets_picker","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fluttercandies.png","metadata":{"files":{"readme":"README-ZH.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"AlexV525","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":["https://www.alexv525.com/wechat.png","https://www.alexv525.com/alipay.jpg"]}},"created_at":"2020-03-26T03:59:21.000Z","updated_at":"2025-04-23T09:06:48.000Z","dependencies_parsed_at":"2023-02-19T16:15:52.313Z","dependency_job_id":"fff3e894-99aa-4ee0-b2e5-d35a5bf0cbaf","html_url":"https://github.com/fluttercandies/flutter_wechat_assets_picker","commit_stats":{"total_commits":897,"total_committers":25,"mean_commits":35.88,"dds":0.09698996655518399,"last_synced_commit":"4d2de12dd601617c4db67c7ef11f538bec6346af"},"previous_names":[],"tags_count":147,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluttercandies%2Fflutter_wechat_assets_picker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluttercandies%2Fflutter_wechat_assets_picker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluttercandies%2Fflutter_wechat_assets_picker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluttercandies%2Fflutter_wechat_assets_picker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fluttercandies","download_url":"https://codeload.github.com/fluttercandies/flutter_wechat_assets_picker/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254041412,"owners_count":22004717,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","flutter","ios","macos","mobile","multiple-assets","picker","video","wechat"],"created_at":"2024-08-01T12:01:44.400Z","updated_at":"2025-05-13T23:07:51.767Z","avatar_url":"https://github.com/fluttercandies.png","language":"Dart","funding_links":["https://github.com/sponsors/AlexV525","https://www.alexv525.com/wechat.png","https://www.alexv525.com/alipay.jpg"],"categories":["组件","Dart","Image [🔝](#readme)","Components"],"sub_categories":["图片","Image"],"readme":"\u003c!-- Copyright 2019 The FlutterCandies author. All rights reserved.\nUse of this source code is governed by an Apache license\nthat can be found in the LICENSE file. --\u003e\n\n# Flutter WeChat Assets Picker\n\n[![pub package](https://img.shields.io/pub/v/wechat_assets_picker?label=%E7%A8%B3%E5%AE%9A%E7%89%88\u0026logo=dart\u0026style=flat-square)](https://pub.flutter-io.cn/packages/wechat_assets_picker)\n[![pub package](https://img.shields.io/pub/v/wechat_assets_picker?color=9d00ff\u0026include_prereleases\u0026label=%E5%BC%80%E5%8F%91%E7%89%88\u0026logo=dart\u0026style=flat-square)](https://pub.flutter-io.cn/packages/wechat_assets_picker)\n[![CodeFactor](https://img.shields.io/codefactor/grade/github/fluttercandies/flutter_wechat_assets_picker?label=%E4%BB%A3%E7%A0%81%E8%B4%A8%E9%87%8F\u0026logo=codefactor\u0026logoColor=%23ffffff\u0026style=flat-square)](https://www.codefactor.io/repository/github/fluttercandies/flutter_wechat_assets_picker)\n\n[![Build status](https://img.shields.io/github/actions/workflow/status/fluttercandies/flutter_wechat_assets_picker/runnable.yml?branch=main\u0026label=CI\u0026logo=github\u0026style=flat-square)](https://github.com/fluttercandies/flutter_wechat_assets_picker/actions/workflows/runnable.yml)\n[![GitHub license](https://img.shields.io/github/license/fluttercandies/flutter_wechat_assets_picker?label=%E5%8D%8F%E8%AE%AE\u0026style=flat-square)](https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/LICENSE)\n[![GitHub stars](https://img.shields.io/github/stars/fluttercandies/flutter_wechat_assets_picker?logo=github\u0026style=flat-square)](https://github.com/fluttercandies/flutter_wechat_assets_picker/stargazers)\n[![GitHub forks](https://img.shields.io/github/forks/fluttercandies/flutter_wechat_assets_picker?logo=github\u0026style=flat-square)](https://github.com/fluttercandies/flutter_wechat_assets_picker/network)\n\n[![Awesome Flutter](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/Solido/awesome-flutter)\n\u003ca target=\"_blank\" href=\"https://jq.qq.com/?_wv=1027\u0026k=5bcc0gy\"\u003e\u003cimg border=\"0\" src=\"https://pub.idqqimg.com/wpa/images/group.png\" alt=\"FlutterCandies\" title=\"FlutterCandies\"\u003e\u003c/a\u003e\n\nLanguage: [English](README.md) | 中文\n\n基于 **微信 UI** 的 Flutter **图片选择器（同时支持视频和音频）**。\n\n当前的界面设计基于的微信版本：**8.0.51**\n界面更新将在微信版本更新后随时进行跟进。\n\n如果你需要拍照及录制视频，请先查看示例的详细用法，\n并前往 [wechat_camera_picker][wechat_camera_picker pub]。\n该插件是独立扩展，需要结合使用。\n\n查看 [迁移指南][] 了解如何从破坏性改动中迁移为可用代码。\n\n## 版本兼容\n\n该插件仅保证能与 **stable 渠道的 Flutter SDK** 配合使用。\n我们不会为其他渠道的 Flutter SDK 做实时支持。\n\n|        | 3.7 | 3.10 | 3.13 | 3.16 | 3.22 |\n|--------|:---:|:----:|:----:|:----:|:----:|\n| 9.5.0+ |  ❌  |  ❌   |  ❌   |  ❌   |  ✅   |\n| 8.9.0+ |  ❌  |  ❌   |  ❌   |  ✅   |  ❌   |\n| 8.7.0+ |  ❌  |  ❌   |  ✅   |  ❌   |  ❌   |\n| 8.5.0+ |  ❌  |  ✅   |  ❌   |  ❌   |  ❌   |\n| 8.4.0+ |  ✅  |  ❌   |  ❌   |  ❌   |  ❌   |\n\n如果在 `flutter pub get` 时遇到了 `resolve conflict` 失败问题，\n请使用 `dependency_overrides` 解决。\n\n## 主要使用的 package\n\n该插件基于这些优秀的 package 构建：\n\n| Name                                 | Features      |\n|:-------------------------------------|:--------------|\n| [photo_manager][photo_manager pub]   | 资源的基础抽象和管理。   |\n| [extended_image][extended_image pub] | 以熟悉的操作预览所有资源。 |\n| [provider][provider pub]             | 协助选择器管理器内部状态。 |\n| [video_player][video_player pub]     | 播放对应的视频和音频。   |\n\n这些 package 在该插件中的实现已相对稳定。\n如果你在使用中发现于它们相关的问题，\n请先在本插件的问题跟踪中报告相关问题。\n\n\u003cdetails\u003e\n  \u003csummary\u003e目录列表\u003c/summary\u003e\n\n\u003c!-- TOC --\u003e\n* [Flutter WeChat Assets Picker](#flutter-wechat-assets-picker)\n  * [版本兼容](#版本兼容)\n  * [主要使用的 package](#主要使用的-package)\n  * [特性 ✨](#特性-)\n    * [特别提醒 📝](#特别提醒-)\n  * [项目展柜 🖼️](#项目展柜-)\n  * [截图 📸](#截图-)\n  * [开始前的注意事项 ‼️](#开始前的注意事项-)\n  * [准备工作 🍭](#准备工作-)\n    * [Flutter](#flutter)\n    * [Android](#android)\n      * [权限](#权限)\n    * [iOS](#ios)\n    * [macOS](#macos)\n  * [使用方法 📖](#使用方法-)\n    * [国际化](#国际化)\n    * [简单的使用方法](#简单的使用方法)\n    * [更详细的使用方法](#更详细的使用方法)\n      * [展示选中的资源](#展示选中的资源)\n      * [注册资源变化回调](#注册资源变化回调)\n      * [在表单数据中上传 `AssetEntity`](#在表单数据中上传-assetentity)\n        * [使用 `http`](#使用-http)\n        * [使用 `dio`](#使用-dio)\n    * [自定义选择器](#自定义选择器)\n  * [常见问题 ❔](#常见问题-)\n    * [修改默认相册名称（将 `Recent` 改为其他）](#修改默认相册名称将-recent-改为其他)\n    * [Execution failed for task ':photo_manager:compileDebugKotlin'](#execution-failed-for-task-photo_managercompiledebugkotlin)\n    * [从 `File` 或 `Uint8List` 创建 `AssetEntity` 的方法](#从-file-或-uint8list-创建-assetentity-的方法)\n    * [控制台提示 'Failed to find GeneratedAppGlideModule'](#控制台提示-failed-to-find-generatedappglidemodule)\n  * [致谢](#致谢)\n\u003c!-- TOC --\u003e\n\u003c/details\u003e\n\n## 特性 ✨\n\n- ♿ 完整的无障碍支持，包括 **TalkBack** 和 **VoiceOver**\n- ♻️ 支持基于代理重载的全量自定义\n- 🎏 完全可自定义的基于 `ThemeData` 的主题\n- 💚 复刻微信风格（甚至优化了更多的细节）\n- ⚡️ 根据配置调节的性能优化\n- 📷 图片资源支持\n  - 🔬 HEIF 格式图片支持 \u003ca href=\"#特别提醒-\"\u003e\u003csup\u003e(1)\u003c/sup\u003e\u003c/a\u003e\n- 🎥 视频资源支持\n- 🎶 音频资源支持 \u003ca href=\"#notes-\"\u003e\u003csup\u003e(2)\u003c/sup\u003e\u003c/a\u003e\n- 1️⃣ 单选模式模式\n- 💱 国际化 (i18n) 支持\n  - ⏪ RTL 语言支持\n- ➕ 特殊 widget 构建支持\n- 🗂 自定义路径排序支持\n- 📝 自定义文本构建支持\n- ⏳ 自定义筛选规则支持\n- 💻 支持 MacOS\n\n### 特别提醒 📝\n\n1. HEIF (HEIC) 图片支持获取和转换，但是它们的显示依托于 Flutter 的图片解析。\n   在此 issue 中 [flutter/flutter#20522](https://github.com/flutter/flutter/issues/20522) 有所说明。\n   若要用于显示，请使用 `entity.file` 或 `AssetEntityImage` 进行处理。\n2. 由于 iOS 和 macOS 的系统限制，在获取音频时只能获取应用沙盒环境内的音频。\n\n## 项目展柜 🖼️\n\n| name                | pub                                                                                                                        | github                                                                                                                                        |\n|:--------------------|:---------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------|\n| insta_assets_picker | [![pub package](https://img.shields.io/pub/v/insta_assets_picker)](https://pub.flutter-io.cn/packages/insta_assets_picker) | [![star](https://img.shields.io/github/stars/LeGoffMael/insta_assets_picker?style=social)](https://github.com/LeGoffMael/insta_assets_picker) |\n\n## 截图 📸\n\n| ![1](screenshots/README_1.webp)                          | ![2](screenshots/README_2.webp)                          | ![3](screenshots/README_3.webp)                          |\n|----------------------------------------------------------|----------------------------------------------------------|----------------------------------------------------------|\n| ![4](screenshots/README_4.webp)                          | ![5](screenshots/README_5.webp)                          | ![6](screenshots/README_6.webp)                          |\n| ![7](screenshots/README_7.webp)                          | ![8](screenshots/README_8.webp)                          | ![9](screenshots/README_9.webp)                          |\n| ![10](https://pic.alexv525.com/2021-07-05-picker_10.png) | ![10](https://pic.alexv525.com/2021-07-05-picker_11.png) | ![12](https://pic.alexv525.com/2021-07-05-picker_12.png) |\n\n## 开始前的注意事项 ‼️\n\n在开始一切之前，请明确以下两点：\n- 由于理解差异和篇幅限制，并不是所有的内容都会明确地在文档中指出。\n  当你遇到没有找到需求和无法理解的概念时，请先运行项目的示例 example，\n  它可以解决 90% 的常见需求。\n- 该库与 [photo_manager][photo_manager pub] 有强关联性，\n  大部分方法的行为是由 photo_manager 进行控制的，\n  所以请尽可能地确保你了解以下两个类的概念：\n  - 资源（图片/视频/音频） [`AssetEntity`](https://pub.flutter-io.cn/documentation/photo_manager/latest/photo_manager/AssetEntity-class.html)\n  - 资源合集（相册或集合概念） [`AssetPathEntity`](https://pub.flutter-io.cn/documentation/photo_manager/latest/photo_manager/AssetPathEntity-class.html)\n\n当你有与相关的 API 和行为的疑问时，你可以查看\n[photo_manager API 文档][] 了解更多细节。\n\n众多使用场景都已包含在示例中。\n在你提出任何问题之前，请仔细并完整地查看和使用示例。\n\n## 准备工作 🍭\n\n### Flutter\n\n执行 `flutter pub add wechat_assets_picker`，\n或者将 `wechat_assets_picker` 手动添加至 `pubspec.yaml` 引用。\n\n```yaml\ndependencies:\n  wechat_assets_picker: ^latest_version\n```\n\n最新的 **稳定** 版本是:\n[![pub package](https://img.shields.io/pub/v/wechat_assets_picker?logo=dart\u0026label=stable\u0026style=flat-square)](https://pub.flutter-io.cn/packages/wechat_assets_picker)\n\n最新的 **开发** 版本是:\n[![pub package](https://img.shields.io/pub/v/wechat_assets_picker?color=9d00ff\u0026include_prereleases\u0026label=dev\u0026logo=dart\u0026style=flat-square)](https://pub.flutter-io.cn/packages/wechat_assets_picker)\n\n在你的代码中导入：\n\n```dart\nimport 'package:wechat_assets_picker/wechat_assets_picker.dart';\n```\n\n### Android\n\n在使用这个 package 时，请确保\n`compileSdkVersion` 和 `targetSdkVersion` 升级到 `33`。\n否则，在 Android 13 设备上将有可能无法加载任何资源。\n\n#### 权限\n\n| Name                     | 必需  | 已声明 | 最高 API 版本 | 其他          |\n|--------------------------|-----|-----|-----------|-------------|\n| `READ_EXTERNAL_STORAGE`  | 是   | 是   | 32        |             |\n| `WRITE_EXTERNAL_STORAGE` | 否   | 否   | 29        |             |\n| `ACCESS_MEDIA_LOCATION`  | 是*  | 否   | N/A       | 读取 EXIF 时必需 |\n| `READ_MEDIA_IMAGES`      | 是*  | 是   | N/A       | 读取图片时必需     | \n| `READ_MEDIA_VIDEO`       | 是*  | 是   | N/A       | 读取视频时必需     | \n| `READ_MEDIA_AUDIO`       | 是*  | 是   | N/A       | 读取音频时必需     |\n\n如果你的目标 SDK 版本大于 33，且你不需要获取图片、视频或者音频，\n你可以考虑只声明需要的权限，具体如下：\n\n```xml\n\u003cmanifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    package=\"com.your.app\"\u003e\n    \u003c!--请求图片和视频权限--\u003e\n    \u003cuses-permission android:name=\"android.permission.READ_MEDIA_IMAGES\" /\u003e\n    \u003cuses-permission android:name=\"android.permission.READ_MEDIA_VIDEO\" /\u003e\n    \u003c!--如果不需要获取音频，移除或者注释 READ_MEDIA_AUDIO--\u003e\n    \u003c!--\u003cuses-permission android:name=\"android.permission.READ_MEDIA_AUDIO\" /\u003e--\u003e\n\u003c/manifest\u003e\n```\n\n### iOS\n\n1. 在 `ios/Podfile` 中指定最低构建版本至 **11.0**。\n   ```ruby\n   platform :ios, '11.0'\n   ```\n   如果该行以 `#` (注释) 开头，请把 `#` 删除。\n2. 将以下内容添加至 `Info.plist`。\n```\n\u003ckey\u003eNSPhotoLibraryUsageDescription\u003c/key\u003e\n\u003cstring\u003e你的相册权限描述\u003c/string\u003e\n```\n\n### macOS\n\n1. 在 `macos/Podfile` 中指定最低构建版本至 **10.15**。\n   ```Podfile\n   platform :osx, '10.15'\n   ```\n   如果该行以 `#` (注释) 开头，请把 `#` 删除。\n2. 使用 **Xcode** 打开 `macos/Runner.xcworkspace`。\n   接着将 macOS 的最低构建版本提升至 **10.15**。\n3. 与 [iOS](#iOS) 一样，添加相同的内容到 `Info.plist` 里。\n\n## 使用方法 📖\n\n### 国际化\n\n当你在选择资源的时候，package 会通过你的 `BuildContext`\n读取 `Locale?`，返回对应语言的文字代理实现。\n请确保你可以通过 `BuildContext` 获取到 `Locale`，否则将会 **默认展示中文文字**。\n\n内置的语言文字实现有：\n* 简体中文 (默认)\n* English\n* העברית\n* Deutsche\n* Локализация\n* 日本語\n* مة العربية\n* Délégué\n* Tiếng Việt\n* Türkçe Yerelleştirme\n\n如果你想使用自定义或固定的文字实现，请通过\n`AssetPickerConfig.textDelegate` 传递调用。\n\n### 简单的使用方法\n\n```dart\nfinal List\u003cAssetEntity\u003e? result = await AssetPicker.pickAssets(context);\n```\n\n你可以使用 `AssetPickerConfig` 来调整选择时的行为。\n\n```dart\nfinal List\u003cAssetEntity\u003e? result = await AssetPicker.pickAssets(\n  context,\n  pickerConfig: const AssetPickerConfig(),\n);\n```\n\n`AssetPickerConfig` 的成员说明：\n\n| 参数名                               | 类型                                               | 描述                                                   | 默认值                         |\n|-----------------------------------|--------------------------------------------------|------------------------------------------------------|-----------------------------|\n| selectedAssets                    | `List\u003cAssetEntity\u003e?`                             | 已选的资源。确保不重复选择。                                       | `null`                      |\n| maxAssets                         | `int`                                            | 最多选择的图片数量                                            | 9                           |\n| pageSize                          | `int`                                            | 分页加载时每页加载的资源数量。**必须为网格数的倍数。                          | 80                          |\n| gridThumbnailSize                 | `ThumbnailSize`                                  | 预览网格的缩略图大小                                           | `ThumbnailSize.square(200)` |\n| pathThumbnailSize                 | `ThumbnailSize`                                  | 路径选择器的缩略图大小                                          | `ThumbnailSize.square(80)`  |\n| previewThumbnailSize              | `ThumbnailSize?`                                 | 预览时图片的缩略图大小                                          | `null`                      |\n| requestType                       | `RequestType`                                    | 选择器选择资源的类型                                           | `RequestType.common`        |\n| specialPickerType                 | `SpecialPickerType?`                             | 提供一些特殊的选择器类型以整合非常规的选择行为                              | `null`                      |\n| keepScrollOffset                  | `bool`                                           | 选择器是否可以从同样的位置开始选择                                    | `null`                      |\n| sortPathDelegate                  | `SortPathDelegate\u003cAssetPathEntity\u003e?`             | 资源路径的排序实现，可自定义路径排序方法                                 | `CommonSortPathDelegate`    |\n| sortPathsByModifiedDate           | `bool`                                           | 是否结合 `FilterOptionGroup.containsPathModified` 进行路径排序 | `false`                     |\n| filterOptions                     | `PMFilter?`                                      | 允许用户自定义资源过滤条件                                        | `null`                      |\n| gridCount                         | `int`                                            | 选择器网格数量                                              | 4                           |\n| themeColor                        | `Color?`                                         | 选择器的主题色                                              | `Color(0xff00bc56)`         |\n| pickerTheme                       | `ThemeData?`                                     | 选择器的主题提供，包括查看器                                       | `null`                      |\n| textDelegate                      | `AssetPickerTextDelegate?`                       | 选择器的文本代理构建，用于自定义文本                                   | `AssetPickerTextDelegate()` |\n| specialItemPosition               | `SpecialItemPosition`                            | 允许用户在选择器中添加一个自定义item，并指定位置。                          | `SpecialPosition.none`      |\n| specialItemBuilder                | `SpecialItemBuilder?`                            | 自定义item的构造方法                                         | `null`                      |\n| loadingIndicatorBuilder           | `IndicatorBuilder?`                              | 加载器的实现                                               | `null`                      |\n| selectPredicate                   | `AssetSelectPredicate`                           | 判断资源可否被选择                                            | `null`                      |\n| shouldRevertGrid                  | `bool?`                                          | 判断资源网格是否需要倒序排列                                       | `null`                      |\n| limitedPermissionOverlayPredicate | `LimitedPermissionOverlayPredicate?`             | 判断有限的权限情况下是否展示提示页面                                   | `null`                      |\n| pathNameBuilder                   | `PathNameBuilder\u003cAssetPathEntity\u003e?`              | 基于路径（相册）构建自定义名称的方法                                   | `null`                      |\n| assetsChangeCallback              | `AssetsChangeCallback\u003cAssetPathEntity\u003e?`         | 当系统通知资源变化时将调用的回调                                     | `null`                      |\n| assetsChangeRefreshPredicate      | `AssetsChangeRefreshPredicate\u003cAssetPathEntity\u003e?` | 判断资源变化是否根据 call 和当前选中的路径进行更新                         | `null`                      |\n| shouldAutoplayPreview             | `bool`                                           | 预览是否应自动播放                                            | `false`                     |\n| dragToSelect                      | `bool`                                           | 是否开启拖拽选择                                             | `true`                      |\n\n- 当 `maxAssets` 等于 `1`（即单选模式），搭配\n  `SpecialPickerType.noPreview` 使用会在用户点选资源换时立刻选中并返回。\n- `limitedPermissionOverlayPredicate` 不是持久化的，\n  如果你需要在应用下次启动时不再显示权限受限的页面，请自主实现持久化的控制。\n\n### 更详细的使用方法\n\n我们已将常用的调用方法封装在 [example](example) 中。\n你可以在 `example/lib/pages/multi_assets_page.dart` 和\n`example/lib/pages/single_assets_page.dart`\n找到 `List\u003cPickMethod\u003e pickMethods`，\n它分别定义了多选和单选可用的选择模式。\n在选择资源后，资源会暂存并展示在页面下方。\n\n#### 展示选中的资源\n\n`AssetEntityImage` 和 `AssetEntityImageProvider`\n可以为 **图片 \u0026 视频** 展示缩略图，以及展示 **图片的原图**。\n它的使用方法与常见的 `Image` 和 `ImageProvider` 一致。\n\n```dart\nAssetEntityImage(asset, isOriginal: false);\n```\n\n或：\n\n```dart\n/// AssetEntityImageProvider\nImage(image: AssetEntityImageProvider(asset, isOriginal: false));\n```\n\n#### 注册资源变化回调\n\n```dart\n/// 注册回调\nAssetPicker.registerObserve();\n\n/// 取消注册回调\nAssetPicker.unregisterObserve();\n```\n\n#### 在表单数据中上传 `AssetEntity`\n\n`AssetEntity` 包含有多种 I/O 相关的方法可以用于上传。\n**请注意，I/O 相关的方法会消耗性能（通常是时间和内存），它们不应该被频繁调用。**\n\n##### 使用 `http`\n\n`http` package: https://pub.flutter-io.cn/packages/http\n\n`http` package 使用v\n[`MultipartFile`](https://pub.flutter-io.cn/documentation/http/latest/http/MultipartFile-class.html)\n来在请求中处理文件。\n\n示例代码如下：\n```dart\nimport 'package:http/http.dart' as http;\n\nFuture\u003cvoid\u003e upload() async {\n  final entity = await obtainYourEntity();\n  final uri = Uri.https('example.com', 'create');\n  final request = http.MultipartRequest('POST', uri)\n    ..fields['test_field'] = 'test_value'\n    ..files.add(await multipartFileFromAssetEntity(entity));\n  final response = await request.send();\n  if (response.statusCode == 200) {\n    print('Uploaded!');\n  }\n}\n\nFuture\u003chttp.MultipartFile\u003e multipartFileFromAssetEntity(AssetEntity entity) async {\n  http.MultipartFile mf;\n  // Using the file path.\n  final file = await entity.file;\n  if (file == null) {\n    throw StateError('Unable to obtain file of the entity ${entity.id}.');\n  }\n  mf = await http.MultipartFile.fromPath('test_file', file.path);\n  // Using the bytes.\n  final bytes = await entity.originBytes;\n  if (bytes == null) {\n    throw StateError('Unable to obtain bytes of the entity ${entity.id}.');\n  }\n  mf = http.MultipartFile.fromBytes('test_file', bytes);\n  return mf;\n}\n```\n\n##### 使用 `dio`\n\n`dio` package: https://pub.flutter-io.cn/packages/dio\n\n`dio` package 同样使用了\n[`MultipartFile`](https://pub.flutter-io.cn/documentation/dio/latest/dio/MultipartFile-class.html)\n来在请求中处理文件。\n\n示例代码：\n```dart\nimport 'package:dio/dio.dart' as dio;\n\nFuture\u003cvoid\u003e upload() async {\n  final entity = await obtainYourEntity();\n  final uri = Uri.https('example.com', 'create');\n  final response = dio.Dio().requestUri(\n    uri,\n    data: dio.FormData.fromMap({\n      'test_field': 'test_value',\n      'test_file': await multipartFileFromAssetEntity(entity),\n    }),\n  );\n  print('Uploaded!');\n}\n\nFuture\u003cdio.MultipartFile\u003e multipartFileFromAssetEntity(AssetEntity entity) async {\n  dio.MultipartFile mf;\n  // Using the file path.\n  final file = await entity.file;\n  if (file == null) {\n    throw StateError('Unable to obtain file of the entity ${entity.id}.');\n  }\n  mf = await dio.MultipartFile.fromFile(file.path);\n  // Using the bytes.\n  final bytes = await entity.originBytes;\n  if (bytes == null) {\n    throw StateError('Unable to obtain bytes of the entity ${entity.id}.');\n  }\n  mf = dio.MultipartFile.fromBytes(bytes);\n  return mf;\n}\n```\n\n### 自定义选择器\n\n`AssetPickerBuilderDelegate`、`AssetPickerViewerBuilderDelegate`、\n`AssetPickerProvider` 及 `AssetPickerViewerProvider` 均已暴露且可重载。\n使用者可以使用自定义的泛型类型 `\u003cA: 资源, P: 路径\u003e`，\n配合继承与重载，实现对应抽象类和类中的方法。\n更多用法请查看示例中的 `Custom` 页面，\n该页面包含一个以 `\u003cFile, Directory\u003e` 为类型基础的选择器。\n\n想要了解如何完全自定义主题、widget 和布局，前往 [示例](example/lib/customs/pickers)\n查看已有的自定义选择器的实现。\n\n如果你觉得你的实现有价值或能帮助到其他人，欢迎以 PR 的形式进行提交。\n更多细节请阅读 [贡献自定义实现][]。\n\n## 常见问题 ❔\n\n### 修改默认相册名称（将 `Recent` 改为其他）\n\n在 Android 上 `Recent` 是总相册的默认名称，\n总相册是一个实际不存在的概念，它只是原始媒体数据的记录集合。\n\n想要在 Android 上解决这个问题，你可以像这样使用 `pathNameBuilder`：\n```dart\nAssetPickerConfig(\n  pathNameBuilder: (AssetPathEntity path) =\u003e switch (path) {\n    final p when p.isAll =\u003e '最近',\n    // 你也可以将类似的逻辑应用在其他常见的相册上。\n    _ =\u003e path.name,\n  },\n)\n```\n\n其他相册或者其他平台 (iOS/macOS) 上的相册会根据系统语言和配置支持的语言来进行展示。\n`pathNameBuilder` 可以用于任何的相册。\n\n### Execution failed for task ':photo_manager:compileDebugKotlin'\n\n查看 [photo_manager#561][] 了解详细的解决方法。\n\n### 从 `File` 或 `Uint8List` 创建 `AssetEntity` 的方法\n\n如果需要使用此库结合一些拍照需求，\n可通过以下方法将 `File` 或 `Uint8List` 转为 `AssetEntity`。\n\n```dart\nfinal File file = your_file; // 你的 File 对象\nfinal String path = file.path;\nfinal AssetEntity fileEntity = await PhotoManager.editor.saveImageWithPath(\n  path,\n  title: basename(path),\n); // 存入手机并生成 AssetEntity\n\nfinal Uint8List data = your_data; // 你的 Uint8List 对象\nfinal AssetEntity imageEntity = await PhotoManager.editor.saveImage(\n  file.path,\n  title: '带有后缀的名称.jpg',\n); // 存入手机并生成 AssetEntity\n```\n\n**注意：如果不想保留文件，请尽量用 `File` 承载中间操作，**\n否则在调用 `AssetEntity` 的删除时，系统可能会触发弹窗：\n\n```dart\nfinal List\u003cString\u003e result = await PhotoManager.editor.deleteWithIds(\n  \u003cString\u003e[entity.id],\n);\n```\n\n你可以阅读 [photo_manager#from-raw-data][]\n和 [photo_manager#delete-entities][]\n了解更多细节。\n\n### 控制台提示 'Failed to find GeneratedAppGlideModule'\n\n```\nW/Glide   (21133): Failed to find GeneratedAppGlideModule. \n                   You should include an annotationProcessor compile dependency on com.github.bumptech.glide:compiler\n                   in you application ana a @GlideModule annotated AppGlideModule implementation\n                   or LibraryGlideModules will be silently ignored.\n```\n\n`Glide` 通过注解来保证单例，防止单例或版本之间的冲突，\n而因为 `photo_manager` 使用了 `Glide` 提供部分图片功能，\n所以使用它的项目必须实现自己的 `AppGlideModule`。\n请移步 [Glide Generated API 文档][] 了解如何实现。\n\n## 致谢\n\n\u003e IntelliJ IDEA 的每个方面都旨在最大化开发者生产力。结合智能编码辅助与符合人体工程学的设计，让开发不仅高效，更成为一种享受。\n\n感谢 [JetBrains](https://www.jetbrains.com/?from=fluttercandies)\n为开源项目提供免费的\n[IntelliJ IDEA](https://www.jetbrains.com/idea/?from=fluttercandies)\n等 IDE 的授权。\n\n[\u003cimg src=\"https://github.com/fluttercandies/flutter_wechat_assets_picker/raw/main/.github/jetbrains-variant.png\" width=\"200\"/\u003e](https://www.jetbrains.com/?from=fluttercandies)\n\n\n[photo_manager pub]: https://pub.flutter-io.cn/packages/photo_manager\n[extended_image pub]: https://pub.flutter-io.cn/packages/extended_image\n[provider pub]: https://pub.flutter-io.cn/packages/provider\n[video_player pub]: https://pub.flutter-io.cn/packages/video_player\n[wechat_camera_picker pub]: https://pub.flutter-io.cn/packages/wechat_camera_picker\n[迁移指南]: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/guides/migration_guide.md\n[photo_manager API 文档]: https://pub.flutter-io.cn/documentation/photo_manager/latest/\n[Glide Generated API 文档]: https://muyangmin.github.io/glide-docs-cn/doc/generatedapi.html\n[贡献自定义实现]: https://github.com/fluttercandies/flutter_wechat_assets_picker/blob/main/example/lib/customs/CONTRIBUTING.md\n[photo_manager#561]: https://github.com/fluttercandies/flutter_photo_manager/issues/561\n[photo_manager#from-raw-data]: https://github.com/fluttercandies/flutter_photo_manager#from-raw-data\n[photo_manager#delete-entities]: https://github.com/fluttercandies/flutter_photo_manager#delete-entities\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffluttercandies%2Fflutter_wechat_assets_picker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffluttercandies%2Fflutter_wechat_assets_picker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffluttercandies%2Fflutter_wechat_assets_picker/lists"}