lucky1213 преди 4 години
родител
ревизия
015f433e38
променени са 9 файла, в които са добавени 142 реда и са изтрити 61 реда
  1. 1
    1
      example/ios/Flutter/.last_build_id
  2. 4
    4
      example/lib/main.dart
  3. BIN
      lib/fonts/iconfont.ttf
  4. 48
    41
      lib/photo.dart
  5. 20
    14
      lib/src/delegate/badge_delegate.dart
  6. 10
    0
      lib/src/engine/iconfont.dart
  7. 38
    0
      lib/src/permission_utils.dart
  8. 14
    0
      pubspec.lock
  9. 7
    1
      pubspec.yaml

+ 1
- 1
example/ios/Flutter/.last_build_id Целия файл

@@ -1 +1 @@
1
-894f424b8531a69bd75214bc0c525b8a
1
+627ffd90bffd0082b3a38187f39f4b86

+ 4
- 4
example/lib/main.dart Целия файл

@@ -171,8 +171,8 @@ class _MyHomePageState extends State<MyHomePage> with LoadingDelegate {
171 171
     /// context is required, other params is optional.
172 172
     /// context is required, other params is optional.
173 173
     /// context is required, other params is optional.
174
-    List<AssetPathEntity> pathList2 = await PhotoManager.getAssetPathList(
175
-        hasAll: true, type: RequestType.image,);
174
+    // List<AssetPathEntity> pathList2 = await PhotoManager.getAssetPathList(
175
+    //     hasAll: true, type: RequestType.image,);
176 176
         if (!single) {
177 177
           PickedEntity entity = await PhotoPicker.pickAsset(
178 178
       context: context,
@@ -184,7 +184,7 @@ class _MyHomePageState extends State<MyHomePage> with LoadingDelegate {
184 184
       thumbSize: 150,
185 185
       sortDelegate: SortDelegate.common,
186 186
       pickType: type,
187
-      photoPathList: pathList2,
187
+      //photoPathList: pathList2,
188 188
     );
189 189
 
190 190
     if (entity == null || entity.asset.isEmpty) {
@@ -213,7 +213,7 @@ class _MyHomePageState extends State<MyHomePage> with LoadingDelegate {
213 213
             thumbSize: 150,
214 214
             sortDelegate: SortDelegate.common,
215 215
             pickType: type,
216
-            photoPathList: pathList2,
216
+            // photoPathList: pathList2,
217 217
           );
218 218
           print(asset);
219 219
         }

BIN
lib/fonts/iconfont.ttf Целия файл


+ 48
- 41
lib/photo.dart Целия файл

@@ -1,11 +1,11 @@
1 1
 library photo;
2 2
 
3 3
 import 'dart:async';
4
-import 'dart:io';
5 4
 
6 5
 import 'package:flutter/material.dart';
7 6
 import 'package:image_picker/image_picker.dart';
8 7
 import 'package:photo/src/entity/_theme.dart';
8
+import 'package:photo/src/permission_utils.dart';
9 9
 import 'package:photo/src/ui/page/photo_list_page.dart';
10 10
 import 'package:photo/src/ui/page/photo_main_page.dart';
11 11
 
@@ -17,7 +17,6 @@ import 'package:photo/src/delegate/loading_delegate.dart';
17 17
 import 'package:photo/src/delegate/sort_delegate.dart';
18 18
 import 'package:photo/src/entity/options.dart';
19 19
 import 'package:photo/src/provider/i18n_provider.dart';
20
-import 'package:photo/src/ui/dialog/not_permission_dialog.dart';
21 20
 import 'package:provider/provider.dart';
22 21
 
23 22
 import 'src/provider/config_provider.dart';
@@ -29,8 +28,8 @@ export 'package:photo/src/provider/i18n_provider.dart'
29 28
 export 'package:photo/src/entity/options.dart' show PickType, PickedEntity;
30 29
 export 'package:photo/src/delegate/badge_delegate.dart';
31 30
 export 'package:photo/src/entity/_theme.dart';
32
-export 'package:image_picker/image_picker.dart' show CameraDevice;
33
-export 'package:photo_manager/photo_manager.dart' show AssetEntity;
31
+export 'package:image_picker/image_picker.dart' show CameraDevice, PickedFile;
32
+export 'package:photo_manager/photo_manager.dart' show AssetEntity, AssetType;
34 33
 
35 34
 class PhotoPicker {
36 35
   static PhotoPicker _instance;
@@ -61,7 +60,7 @@ class PhotoPicker {
61 60
     @required BuildContext context,
62 61
     int rowCount = 4,
63 62
     int maxSelected = 9,
64
-    double padding = 1,
63
+    double padding = 0.5,
65 64
     double itemRadio = 1.0,
66 65
     int thumbSize = 180,
67 66
     PhotoTheme theme,
@@ -91,7 +90,7 @@ class PhotoPicker {
91 90
       sortDelegate: sortDelegate,
92 91
       checkBoxBuilderDelegate: DefaultCheckBoxBuilderDelegate(),
93 92
       loadingDelegate: loadingDelegate,
94
-      badgeDelegate: DefaultBadgeDelegate(),
93
+      badgeDelegate: DurationBadgeDelegate(),
95 94
       pickType: pickType,
96 95
     );
97 96
 
@@ -104,11 +103,10 @@ class PhotoPicker {
104 103
     );
105 104
   }
106 105
 
107
-
108 106
   static Future<AssetEntity> pickSingleAsset({
109 107
     @required BuildContext context,
110 108
     int rowCount = 4,
111
-    double padding = 1,
109
+    double padding = 0.5,
112 110
     double itemRadio = 1.0,
113 111
     int thumbSize = 180,
114 112
     PhotoTheme theme,
@@ -139,19 +137,24 @@ class PhotoPicker {
139 137
     return null;
140 138
   }
141 139
 
142
-  static Future<File> pickCamera({
140
+  static Future<PickedFile> pickCamera({
143 141
     double maxWidth,
144 142
     double maxHeight,
145 143
     int imageQuality,
146 144
     CameraDevice preferredCameraDevice = CameraDevice.rear,
147 145
   }) async {
148
-    return ImagePicker.pickImage(
149
-      source: ImageSource.camera,
150
-      maxWidth: maxWidth,
151
-      maxHeight: maxHeight,
152
-      imageQuality: imageQuality,
153
-      preferredCameraDevice: preferredCameraDevice,
154
-    );
146
+    final bool status = await PermissionUtils.canPermission(Permission.camera);
147
+    if (!status) {
148
+      throw 'permission denied';
149
+    } else {
150
+      return ImagePicker().getImage(
151
+        source: ImageSource.camera,
152
+        maxWidth: maxWidth,
153
+        maxHeight: maxHeight,
154
+        imageQuality: imageQuality,
155
+        preferredCameraDevice: preferredCameraDevice,
156
+      );
157
+    }
155 158
   }
156 159
 
157 160
   Future<PickedEntity> _pickAsset(
@@ -161,15 +164,18 @@ class PhotoPicker {
161 164
     List<AssetPathEntity> photoList,
162 165
     List<AssetEntity> pickedAssetList,
163 166
   ) async {
164
-    await requestPermission(context, provider: provider);
165
-
166
-    return _openGalleryContentPage(
167
-      context,
168
-      options,
169
-      provider,
170
-      photoList,
171
-      pickedAssetList,
172
-    );
167
+    final bool status = await PermissionUtils.canMultiplePermission([Permission.photos, Permission.storage]);
168
+    if (!status) {
169
+      throw 'permission denied';
170
+    } else {
171
+      return _openGalleryContentPage(
172
+        context,
173
+        options,
174
+        provider,
175
+        photoList,
176
+        pickedAssetList,
177
+      );
178
+    }
173 179
   }
174 180
 
175 181
   static Widget buildGallery({
@@ -201,7 +207,7 @@ class PhotoPicker {
201 207
       sortDelegate: sortDelegate,
202 208
       checkBoxBuilderDelegate: DefaultCheckBoxBuilderDelegate(),
203 209
       loadingDelegate: loadingDelegate,
204
-      badgeDelegate: DefaultBadgeDelegate(),
210
+      badgeDelegate: DurationBadgeDelegate(),
205 211
       pickType: pickType,
206 212
     );
207 213
     assert(provider != null, "provider must be not null");
@@ -222,21 +228,22 @@ class PhotoPicker {
222 228
     );
223 229
   }
224 230
 
225
-  Future<void> requestPermission(BuildContext context,
226
-      {@required I18nProvider provider}) async {
227
-    var requestPermission = await PhotoManager.requestPermission();
228
-    if (requestPermission != true) {
229
-      var result = await showDialog(
230
-        context: context,
231
-        builder: (ctx) => NotPermissionDialog(
232
-          provider.getNotPermissionText(),
233
-        ),
234
-      );
235
-      if (result == true) {
236
-        PhotoManager.openSetting();
237
-      }
238
-      return null;
239
-    }
231
+  Future<bool> requestPermission({@required I18nProvider provider, @required List<Permission> permissions}) async {
232
+    final bool status =
233
+        await PermissionUtils.canMultiplePermission(permissions);
234
+    // if (!status) {
235
+    //   var result = await showDialog(
236
+    //     context: context,
237
+    //     builder: (ctx) => NotPermissionDialog(
238
+    //       provider.getNotPermissionText(),
239
+    //     ),
240
+    //   );
241
+    //   if (result == true) {
242
+    //     PhotoManager.openSetting();
243
+    //   }
244
+    //   return false;
245
+    // }
246
+    return status;
240 247
   }
241 248
 
242 249
   Future<PickedEntity> _openGalleryContentPage(

+ 20
- 14
lib/src/delegate/badge_delegate.dart Целия файл

@@ -1,4 +1,5 @@
1 1
 import 'package:flutter/material.dart';
2
+import 'package:photo/src/engine/iconfont.dart';
2 3
 import 'package:photo_manager/photo_manager.dart';
3 4
 
4 5
 abstract class BadgeDelegate {
@@ -51,28 +52,33 @@ class DurationBadgeDelegate extends BadgeDelegate {
51 52
   Widget buildBadge(BuildContext context, AssetType type, Duration duration) {
52 53
     if (type == AssetType.video) {
53 54
       var s = duration.inSeconds % 60;
54
-      var m = duration.inMinutes % 60;
55
-      var h = duration.inHours;
55
+      var m = duration.inMinutes;
56 56
 
57
-      String text =
58
-          "$h:${m.toString().padLeft(2, '0')}:${s.toString().padLeft(2, '0')}";
57
+      String text = "${m.toString().padLeft(2, '0')}:${s.toString().padLeft(2, '0')}";
59 58
 
60 59
       return Padding(
61
-        padding: const EdgeInsets.all(2.0),
60
+        padding: const EdgeInsets.all(4.0),
62 61
         child: Align(
63 62
           alignment: alignment,
64 63
           child: Container(
65
-            decoration: BoxDecoration(
66
-              color: Theme.of(context).primaryColor.withOpacity(0.65),
64
+            child: Row(
65
+              children: [
66
+                Icon(MutliImagePickerFont.video, size: 20, color: Colors.white,),
67
+                Padding(
68
+                  padding: EdgeInsets.only(left: 6.0),
69
+                  child: Text(
70
+                    text,
71
+                    style: const TextStyle(
72
+                      fontSize: 14.0,
73
+                      color: Colors.white,
74
+                    ),
75
+                  ),
76
+                ),
77
+              ],
67 78
             ),
68
-            child: Text(
69
-              text,
70
-              style: const TextStyle(
71
-                fontSize: 12.0,
72
-                color: Colors.white,
73
-              ),
79
+            padding: EdgeInsets.symmetric(
80
+              horizontal: 2,
74 81
             ),
75
-            padding: const EdgeInsets.all(4.0),
76 82
           ),
77 83
         ),
78 84
       );

+ 10
- 0
lib/src/engine/iconfont.dart Целия файл

@@ -0,0 +1,10 @@
1
+
2
+import 'package:flutter/material.dart';
3
+
4
+class MutliImagePickerFont {
5
+  MutliImagePickerFont._();
6
+  static const String _family = 'PhotoFont';
7
+  static const String _fontPackage = 'photo';
8
+
9
+  static const IconData video = IconData(0xe6bd, fontFamily: _family, fontPackage: _fontPackage);
10
+}

+ 38
- 0
lib/src/permission_utils.dart Целия файл

@@ -0,0 +1,38 @@
1
+import 'dart:io';
2
+
3
+import 'package:permission_handler/permission_handler.dart';
4
+
5
+export 'package:permission_handler/permission_handler.dart';
6
+
7
+class PermissionUtils {
8
+  static Future<bool> canPermission(Permission permission, [bool request = true]) async {
9
+    if (permission == Permission.storage && Platform.isIOS) {
10
+      return true;
11
+    }
12
+    if (permission == Permission.photos && Platform.isAndroid) {
13
+      return true;
14
+    }
15
+    if (!await permission.status.isGranted) {
16
+      if (request) {
17
+        final PermissionStatus status =  await permission.request();
18
+        if (status.isDenied) {
19
+          openAppSettings();
20
+        }
21
+        return status.isGranted;
22
+      }
23
+      return false;
24
+    } else {
25
+      return true;
26
+    }
27
+  }
28
+
29
+  static Future<bool> canMultiplePermission(List<Permission> list, [bool request = true]) async {
30
+    for (final Permission permission in list) {
31
+      if (!await canPermission(permission, request)) {
32
+        return false;
33
+      }
34
+    }
35
+
36
+    return true;
37
+  }
38
+}

+ 14
- 0
pubspec.lock Целия файл

@@ -123,6 +123,20 @@ packages:
123 123
       url: "https://pub.flutter-io.cn"
124 124
     source: hosted
125 125
     version: "1.9.0"
126
+  permission_handler:
127
+    dependency: "direct main"
128
+    description:
129
+      name: permission_handler
130
+      url: "https://pub.flutter-io.cn"
131
+    source: hosted
132
+    version: "5.0.1+1"
133
+  permission_handler_platform_interface:
134
+    dependency: transitive
135
+    description:
136
+      name: permission_handler_platform_interface
137
+      url: "https://pub.flutter-io.cn"
138
+    source: hosted
139
+    version: "2.0.1"
126 140
   photo_manager:
127 141
     dependency: "direct main"
128 142
     description:

+ 7
- 1
pubspec.yaml Целия файл

@@ -1,6 +1,6 @@
1 1
 name: photo
2 2
 description: image picker, multi picker support video/icloud asset, use flutter as ui, if you want to build custom ui, you just use photo_manager.
3
-version: 0.5.2
3
+version: 0.5.3
4 4
 author: caijinglong<cjl_spy@163.com>
5 5
 homepage: https://github.com/CaiJingLong/flutter_photo
6 6
 
@@ -14,6 +14,7 @@ dependencies:
14 14
   photo_manager: 0.5.1
15 15
   provider: ^4.0.5
16 16
   image_picker: ^0.6.5
17
+  permission_handler: ^5.0.0+hotfix.8
17 18
 
18 19
 dev_dependencies:
19 20
   flutter_test:
@@ -24,6 +25,11 @@ dev_dependencies:
24 25
 
25 26
 # The following section is specific to Flutter.
26 27
 flutter:
28
+  uses-material-design: true
29
+  fonts:
30
+    - family: PhotoFont
31
+      fonts:
32
+        - asset: lib/fonts/iconfont.ttf
27 33
   # To add assets to your package, add an assets section, like this:
28 34
   # assets:
29 35
   #  - images/a_dot_burr.jpeg