説明なし

photo.dart 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. library photo;
  2. import 'dart:async';
  3. import 'package:flutter/material.dart';
  4. import 'package:photo/src/entity/_theme.dart';
  5. import 'package:photo/src/ui/page/photo_list_page.dart';
  6. import 'package:photo/src/ui/page/photo_main_page.dart';
  7. import 'package:photo_manager/photo_manager.dart';
  8. import 'package:photo/src/delegate/badge_delegate.dart';
  9. import 'package:photo/src/delegate/checkbox_builder_delegate.dart';
  10. import 'package:photo/src/delegate/loading_delegate.dart';
  11. import 'package:photo/src/delegate/sort_delegate.dart';
  12. import 'package:photo/src/entity/options.dart';
  13. import 'package:photo/src/provider/i18n_provider.dart';
  14. import 'package:photo/src/ui/dialog/not_permission_dialog.dart';
  15. import 'package:provider/provider.dart';
  16. import 'src/provider/config_provider.dart';
  17. export 'package:photo/src/delegate/checkbox_builder_delegate.dart';
  18. export 'package:photo/src/delegate/loading_delegate.dart';
  19. export 'package:photo/src/delegate/sort_delegate.dart';
  20. export 'package:photo/src/provider/i18n_provider.dart'
  21. show I18NCustomProvider, I18nProvider, CNProvider, ENProvider;
  22. export 'package:photo/src/entity/options.dart' show PickType;
  23. export 'package:photo/src/delegate/badge_delegate.dart';
  24. export 'package:photo/src/entity/_theme.dart';
  25. class PhotoPicker {
  26. static PhotoPicker _instance;
  27. PhotoPicker._();
  28. factory PhotoPicker() {
  29. _instance ??= PhotoPicker._();
  30. return _instance;
  31. }
  32. static const String rootRouteName = "photo_picker_image";
  33. /// 没有授予权限的时候,会开启一个dialog去帮助用户去应用设置页面开启权限
  34. /// 确定开启设置页面,取消关闭弹窗,无论选择什么,返回值都是null
  35. ///
  36. ///
  37. /// 当用户给予权限后
  38. ///
  39. /// 当用户确定时,返回一个图片[AssetEntity]列表
  40. ///
  41. /// 当用户取消时返回一个空数组
  42. ///
  43. /// [photoPathList] 一旦设置 则 [pickType]参数无效
  44. ///
  45. /// [pickedAssetList] 已选择的asset
  46. ///
  47. /// 关于参数可以查看readme文档介绍
  48. ///
  49. /// if user not grand permission, then return null and show a dialog to help user open setting.
  50. /// sure is open setting cancel ,cancel to dismiss dialog, return null
  51. ///
  52. /// when user give permission.
  53. ///
  54. /// when user sure , return a [AssetEntity] of [List]
  55. ///
  56. /// when user cancel selected,result is empty list
  57. ///
  58. /// when [photoPathList] is not null , [pickType] invalid
  59. ///
  60. /// [pickedAssetList]: The results of the last selection can be passed in for easy secondary selection.
  61. ///
  62. /// params see readme.md
  63. static Future<List<AssetEntity>> pickAsset({
  64. @required BuildContext context,
  65. int rowCount = 4,
  66. int maxSelected = 9,
  67. double padding = 1,
  68. double itemRadio = 1.0,
  69. int thumbSize = 180,
  70. PhotoTheme theme,
  71. I18nProvider provider = I18nProvider.chinese,
  72. SortDelegate sortDelegate,
  73. LoadingDelegate loadingDelegate,
  74. PickType pickType = PickType.all,
  75. List<AssetPathEntity> photoPathList,
  76. List<AssetEntity> pickedAssetList,
  77. }) {
  78. assert(provider != null, "provider must be not null");
  79. assert(context != null, "context must be not null");
  80. assert(pickType != null, "pickType must be not null");
  81. sortDelegate ??= SortDelegate.common;
  82. loadingDelegate ??= DefaultLoadingDelegate();
  83. var options = Options(
  84. rowCount: rowCount,
  85. maxSelected: maxSelected,
  86. itemRadio: itemRadio,
  87. padding: padding,
  88. theme: theme ?? PhotoTheme.fallback(context),
  89. thumbSize: thumbSize,
  90. sortDelegate: sortDelegate,
  91. checkBoxBuilderDelegate: DefaultCheckBoxBuilderDelegate(),
  92. loadingDelegate: loadingDelegate,
  93. badgeDelegate: DefaultBadgeDelegate(),
  94. pickType: pickType,
  95. );
  96. return PhotoPicker()._pickAsset(
  97. context,
  98. options,
  99. provider,
  100. photoPathList,
  101. pickedAssetList,
  102. );
  103. }
  104. Future<List<AssetEntity>> _pickAsset(
  105. BuildContext context,
  106. Options options,
  107. I18nProvider provider,
  108. List<AssetPathEntity> photoList,
  109. List<AssetEntity> pickedAssetList,
  110. ) async {
  111. await requestPermission(context, provider: provider);
  112. return _openGalleryContentPage(
  113. context,
  114. options,
  115. provider,
  116. photoList,
  117. pickedAssetList,
  118. );
  119. }
  120. static Widget buildGallery({
  121. @required BuildContext context,
  122. double padding = 1,
  123. double itemHeight,
  124. @required double itemWidth,
  125. int thumbSize = 180,
  126. PhotoTheme theme,
  127. I18nProvider provider = I18nProvider.chinese,
  128. SortDelegate sortDelegate,
  129. LoadingDelegate loadingDelegate,
  130. PickType pickType = PickType.all,
  131. List<AssetPathEntity> photoPathList,
  132. List<AssetEntity> pickedAssetList,
  133. void Function(List<AssetEntity> value) onSelected,
  134. }) {
  135. sortDelegate ??= SortDelegate.common;
  136. loadingDelegate ??= DefaultLoadingDelegate();
  137. var options = ListOptions(
  138. padding: padding,
  139. itemHeight: itemHeight,
  140. itemWidth: itemWidth,
  141. theme: theme ?? PhotoTheme.fallback(context),
  142. thumbSize: thumbSize,
  143. sortDelegate: sortDelegate,
  144. checkBoxBuilderDelegate: DefaultCheckBoxBuilderDelegate(),
  145. loadingDelegate: loadingDelegate,
  146. badgeDelegate: DefaultBadgeDelegate(),
  147. pickType: pickType,
  148. );
  149. assert(provider != null, "provider must be not null");
  150. assert(context != null, "context must be not null");
  151. assert(pickType != null, "pickType must be not null");
  152. return ChangeNotifierProvider(
  153. create: (_) => PhotoProvider(
  154. provider: provider,
  155. options: options,
  156. pickedAssetList: pickedAssetList,
  157. ),
  158. child: PhotoListPage(
  159. onSelected: onSelected,
  160. options: options,
  161. ),
  162. );
  163. }
  164. Future<void> requestPermission(BuildContext context, {@required I18nProvider provider}) async {
  165. var requestPermission = await PhotoManager.requestPermission();
  166. if (requestPermission != true) {
  167. var result = await showDialog(
  168. context: context,
  169. builder: (ctx) => NotPermissionDialog(
  170. provider.getNotPermissionText(),
  171. ),
  172. );
  173. if (result == true) {
  174. PhotoManager.openSetting();
  175. }
  176. return null;
  177. }
  178. }
  179. Future<List<AssetEntity>> _openGalleryContentPage(
  180. BuildContext context,
  181. Options options,
  182. I18nProvider provider,
  183. List<AssetPathEntity> photoList,
  184. List<AssetEntity> pickedAssetList,
  185. ) async {
  186. return Navigator.of(context, rootNavigator: true).push(
  187. MaterialPageRoute(
  188. builder: (ctx) => ChangeNotifierProvider(
  189. create: (_) => PhotoProvider(
  190. provider: provider,
  191. options: options,
  192. pickedAssetList: pickedAssetList,
  193. ),
  194. child: PhotoMainPage(
  195. onClose: (List<AssetEntity> value) {
  196. Navigator.pop(ctx, value);
  197. },
  198. options: options,
  199. photoList: photoList,
  200. ),
  201. ),
  202. ),
  203. );
  204. }
  205. }