Ei kuvausta

photo.dart 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. library photo;
  2. import 'dart:async';
  3. import 'dart:io';
  4. import 'package:flutter/material.dart';
  5. import 'package:image_picker/image_picker.dart';
  6. import 'package:photo/src/entity/_theme.dart';
  7. import 'package:photo/src/ui/page/photo_list_page.dart';
  8. import 'package:photo/src/ui/page/photo_main_page.dart';
  9. import 'package:photo_manager/photo_manager.dart';
  10. import 'package:photo/src/delegate/badge_delegate.dart';
  11. import 'package:photo/src/delegate/checkbox_builder_delegate.dart';
  12. import 'package:photo/src/delegate/loading_delegate.dart';
  13. import 'package:photo/src/delegate/sort_delegate.dart';
  14. import 'package:photo/src/entity/options.dart';
  15. import 'package:photo/src/provider/i18n_provider.dart';
  16. import 'package:photo/src/ui/dialog/not_permission_dialog.dart';
  17. import 'package:provider/provider.dart';
  18. import 'src/provider/config_provider.dart';
  19. export 'package:photo/src/delegate/checkbox_builder_delegate.dart';
  20. export 'package:photo/src/delegate/loading_delegate.dart';
  21. export 'package:photo/src/delegate/sort_delegate.dart';
  22. export 'package:photo/src/provider/i18n_provider.dart'
  23. show I18NCustomProvider, I18nProvider, CNProvider, ENProvider;
  24. export 'package:photo/src/entity/options.dart' show PickType, PickedEntity;
  25. export 'package:photo/src/delegate/badge_delegate.dart';
  26. export 'package:photo/src/entity/_theme.dart';
  27. export 'package:image_picker/image_picker.dart' show CameraDevice;
  28. class PhotoPicker {
  29. static PhotoPicker _instance;
  30. PhotoPicker._();
  31. factory PhotoPicker() {
  32. _instance ??= PhotoPicker._();
  33. return _instance;
  34. }
  35. static const String rootRouteName = "photo_picker_image";
  36. /// 没有授予权限的时候,会开启一个dialog去帮助用户去应用设置页面开启权限
  37. /// 确定开启设置页面,取消关闭弹窗,无论选择什么,返回值都是null
  38. /// 当用户给予权限后
  39. ///
  40. /// 返回一个[PickedEntity] 内有[AssetEntity]以及[isFullImage]
  41. ///
  42. /// 当用户取消时[AssetEntity]返回一个空数组
  43. ///
  44. /// [photoPathList] 一旦设置 则 [pickType]参数无效
  45. ///
  46. /// [pickedAssetList] 已选择的asset
  47. ///
  48. /// 关于参数可以查看readme文档介绍
  49. static Future<PickedEntity> pickAsset({
  50. @required BuildContext context,
  51. int rowCount = 4,
  52. int maxSelected = 9,
  53. double padding = 1,
  54. double itemRadio = 1.0,
  55. int thumbSize = 180,
  56. PhotoTheme theme,
  57. I18nProvider provider = I18nProvider.chinese,
  58. SortDelegate sortDelegate,
  59. LoadingDelegate loadingDelegate,
  60. PickType pickType = PickType.all,
  61. List<AssetPathEntity> photoPathList,
  62. List<AssetEntity> pickedAssetList,
  63. }) {
  64. assert(provider != null, "provider must be not null");
  65. assert(context != null, "context must be not null");
  66. assert(pickType != null, "pickType must be not null");
  67. sortDelegate ??= SortDelegate.common;
  68. loadingDelegate ??= DefaultLoadingDelegate();
  69. var options = Options(
  70. rowCount: rowCount,
  71. maxSelected: maxSelected,
  72. itemRadio: itemRadio,
  73. padding: padding,
  74. theme: theme ?? PhotoTheme.fallback(context),
  75. thumbSize: thumbSize,
  76. sortDelegate: sortDelegate,
  77. checkBoxBuilderDelegate: DefaultCheckBoxBuilderDelegate(),
  78. loadingDelegate: loadingDelegate,
  79. badgeDelegate: DefaultBadgeDelegate(),
  80. pickType: pickType,
  81. );
  82. return PhotoPicker()._pickAsset(
  83. context,
  84. options,
  85. provider,
  86. photoPathList,
  87. pickedAssetList,
  88. );
  89. }
  90. static Future<File> pickCamera({
  91. double maxWidth,
  92. double maxHeight,
  93. int imageQuality,
  94. CameraDevice preferredCameraDevice = CameraDevice.rear,
  95. }) async {
  96. return ImagePicker.pickImage(
  97. source: ImageSource.camera,
  98. maxWidth: maxWidth,
  99. maxHeight: maxHeight,
  100. imageQuality: imageQuality,
  101. preferredCameraDevice: preferredCameraDevice,
  102. );
  103. }
  104. Future<PickedEntity> _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. int maxSelected = 9,
  124. int thumbSize = 180,
  125. double itemRadio = 1.0,
  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. bool isFullImage = false,
  134. void Function(PickedEntity value) onSelected,
  135. }) {
  136. sortDelegate ??= SortDelegate.common;
  137. loadingDelegate ??= DefaultLoadingDelegate();
  138. var options = ListOptions(
  139. padding: padding,
  140. maxSelected: maxSelected,
  141. itemRadio: itemRadio,
  142. theme: theme ?? PhotoTheme.fallback(context),
  143. thumbSize: thumbSize,
  144. sortDelegate: sortDelegate,
  145. checkBoxBuilderDelegate: DefaultCheckBoxBuilderDelegate(),
  146. loadingDelegate: loadingDelegate,
  147. badgeDelegate: DefaultBadgeDelegate(),
  148. pickType: pickType,
  149. );
  150. assert(provider != null, "provider must be not null");
  151. assert(context != null, "context must be not null");
  152. assert(pickType != null, "pickType must be not null");
  153. return ChangeNotifierProvider(
  154. create: (_) => PhotoProvider(
  155. provider: provider,
  156. options: options,
  157. pickedAssetList: pickedAssetList,
  158. ),
  159. child: PhotoListPage(
  160. onSelected: onSelected,
  161. options: options,
  162. isFullImage: isFullImage,
  163. ),
  164. );
  165. }
  166. Future<void> requestPermission(BuildContext context,
  167. {@required I18nProvider provider}) async {
  168. var requestPermission = await PhotoManager.requestPermission();
  169. if (requestPermission != true) {
  170. var result = await showDialog(
  171. context: context,
  172. builder: (ctx) => NotPermissionDialog(
  173. provider.getNotPermissionText(),
  174. ),
  175. );
  176. if (result == true) {
  177. PhotoManager.openSetting();
  178. }
  179. return null;
  180. }
  181. }
  182. Future<PickedEntity> _openGalleryContentPage(
  183. BuildContext context,
  184. Options options,
  185. I18nProvider provider,
  186. List<AssetPathEntity> photoList,
  187. List<AssetEntity> pickedAssetList,
  188. ) async {
  189. return Navigator.of(context, rootNavigator: true).push(
  190. MaterialPageRoute(
  191. builder: (ctx) => ChangeNotifierProvider(
  192. create: (_) => PhotoProvider(
  193. provider: provider,
  194. options: options,
  195. pickedAssetList: pickedAssetList,
  196. ),
  197. child: PhotoMainPage(
  198. onClose: (PickedEntity value) {
  199. Navigator.pop(ctx, value);
  200. },
  201. options: options,
  202. photoList: photoList,
  203. ),
  204. ),
  205. ),
  206. );
  207. }
  208. }