Bez popisu

photo.dart 6.4KB

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