Ver código fonte

修改了lru cache

现在的lru cache和图片尺寸相关联

初始化时的loading

排序的delegate
cjl_macbook 6 anos atrás
pai
commit
132c645760

+ 8
- 0
CHANGELOG.md Ver arquivo

@@ -1,5 +1,13 @@
1 1
 # CHANGELOG
2 2
 
3
+## [0.0.5] add a params
4
+
5
+add the sort delegate to help user sort gallery
6
+
7
+Optimized LruCache
8
+
9
+add a loading refresh indicator in the gallery
10
+
3 11
 ## [0.0.4] fix #1
4 12
 
5 13
 fix request other permission will crash bug

+ 38
- 21
README.md Ver arquivo

@@ -13,7 +13,7 @@ if you want to build custom ui, you just need api to make custom ui. to use [pho
13 13
 
14 14
 ```yaml
15 15
 dependencies:
16
-  photo: ^0.0.4
16
+  photo: ^0.0.5
17 17
 ```
18 18
 
19 19
 ## import
@@ -26,26 +26,27 @@ import 'package:photo_manager/photo_manager.dart';
26 26
 ## use
27 27
 
28 28
 ```dart
29
-  void _pickImage(BuildContext context) async {
30
-    List<ImageEntity> imgList = await PhotoPicker.pickImage(
31
-      context: context, // BuildContext requied
32
-
33
-      /// The following are optional parameters.
34
-      themeColor: Colors.green, // the title color and bottom color
35
-      padding: 5.0, // item padding
36
-      dividerColor: Colors.deepOrange, // divider color
37
-      disableColor: Colors.grey.shade300, // the check box disable color
38
-      itemRadio: 0.88, // the content item radio
39
-      maxSelected: 8, // max picker image count
40
-      provider: CNProvider(), // i18n provider ,default is chinese. , you can custom I18nProvider or use ENProvider()
41
-      rowCount: 5,  // item row count
42
-      textColor: Colors.white, // text color
43
-      thumbSize: 150, // preview thumb size, optional, default is 64
44
-    );
45
-
46
-    imgList.forEach((e) async {
47
-      print(e.id);
48
-    });
29
+  void _pickImage() async {
30
+      List<ImageEntity> imgList = await PhotoPicker.pickImage(
31
+        context: context, // BuildContext requied
32
+
33
+        /// The following are optional parameters.
34
+        themeColor: Colors.green, // the title color and bottom color
35
+        padding: 5.0, // item padding
36
+        dividerColor: Colors.deepOrange, // divider color
37
+        disableColor: Colors.grey.shade300, // the check box disable color
38
+        itemRadio: 0.88, // the content item radio
39
+        maxSelected: 8, // max picker image count
40
+        provider: CNProvider(), // i18n provider ,default is chinese. , you can custom I18nProvider or use ENProvider()
41
+        rowCount: 5,  // item row count
42
+        textColor: Colors.white, // text color
43
+        thumbSize: 150, // preview thumb size , default is 64
44
+        sortDelegate: SortDelegate.common, // default is common ,or you make custom delegate
45
+      );
46
+
47
+      imgList.forEach((e) async {
48
+          print(e.id);
49
+      });
49 50
   }
50 51
 ```
51 52
 
@@ -77,3 +78,19 @@ rootProject.allprojects {
77 78
 if you use the proguard
78 79
 
79 80
 see the [github](https://github.com/bumptech/glide#proguard)
81
+
82
+
83
+## about ios
84
+
85
+Because the album is a privacy privilege, you need user permission to access it. You must to modify the `Info.plist` file in Runner project.
86
+
87
+
88
+like next
89
+
90
+```plist
91
+	<key>NSPhotoLibraryUsageDescription</key>
92
+    <string>App需要您的同意,才能访问相册</string>
93
+```
94
+
95
+xcode like image
96
+![in xcode](https://github.com/CaiJingLong/some_asset/blob/master/flutter_photo2.png)

+ 27
- 20
example/lib/main.dart Ver arquivo

@@ -31,28 +31,32 @@ class _MyHomePageState extends State<MyHomePage> {
31 31
 
32 32
   void _pickImage() async {
33 33
     List<ImageEntity> imgList = await PhotoPicker.pickImage(
34
-      context: context,
35
-      themeColor: Colors.green,
36
-      padding: 5.0,
37
-      dividerColor: Colors.deepOrange,
38
-      disableColor: Colors.grey.shade300,
39
-      itemRadio: 0.88,
40
-      maxSelected: 8,
41
-      provider: CNProvider(),
42
-      rowCount: 5,
43
-      textColor: Colors.white,
44
-      thumbSize: 250,
45
-    );
34
+      context: context, // BuildContext requied
46 35
 
47
-    List<String> r = [];
36
+      /// The following are optional parameters.
37
+      themeColor: Colors.green, // the title color and bottom color
38
+      padding: 5.0, // item padding
39
+      dividerColor: Colors.deepOrange, // divider color
40
+      disableColor: Colors.grey.shade300, // the check box disable color
41
+      itemRadio: 0.88, // the content item radio
42
+      maxSelected: 8, // max picker image count
43
+      provider: CNProvider(), // i18n provider ,default is chinese. , you can custom I18nProvider or use ENProvider()
44
+      rowCount: 5,  // item row count
45
+      textColor: Colors.white, // text color
46
+      thumbSize: 150, // preview thumb size , default is 64
47
+      sortDelegate: SortDelegate.common, // default is common ,or you make custom delegate to sort your gallery
48
+    );
48 49
 
49
-    for(var e in imgList){
50
-      var file = await e.file;
51
-      r.add(file.absolute.path);
50
+    if (imgList == null) {
51
+      currentSelected = "not select item";
52
+    } else {
53
+      List<String> r = [];
54
+      for (var e in imgList) {
55
+        var file = await e.file;
56
+        r.add(file.absolute.path);
57
+      }
58
+      currentSelected = r.join("\n\n");
52 59
     }
53
-
54
-    currentSelected = r.join("\n\n");
55
-
56 60
     setState(() {});
57 61
   }
58 62
 
@@ -64,7 +68,10 @@ class _MyHomePageState extends State<MyHomePage> {
64 68
       ),
65 69
       body: Container(
66 70
         child: Center(
67
-          child: Text('$currentSelected'),
71
+          child: Text(
72
+            '$currentSelected',
73
+            textAlign: TextAlign.center,
74
+          ),
68 75
         ),
69 76
       ),
70 77
       floatingActionButton: new FloatingActionButton(

+ 19
- 7
lib/photo.dart Ver arquivo

@@ -3,13 +3,17 @@ library photo;
3 3
 import 'dart:async';
4 4
 
5 5
 import 'package:flutter/material.dart';
6
+import 'package:photo_manager/photo_manager.dart';
7
+
6 8
 import 'package:photo/src/entity/options.dart';
7 9
 import 'package:photo/src/provider/i18n_provider.dart';
8 10
 import 'package:photo/src/ui/dialog/not_permission_dialog.dart';
9 11
 import 'package:photo/src/ui/photo_app.dart';
10
-import 'package:photo_manager/photo_manager.dart';
12
+import 'package:photo/src/delegate/sort_delegate.dart';
11 13
 
12
-export 'package:photo/src/provider/i18n_provider.dart' show I18NCustomProvider,I18nProvider,CNProvider,ENProvider;
14
+export 'package:photo/src/provider/i18n_provider.dart'
15
+    show I18NCustomProvider, I18nProvider, CNProvider, ENProvider;
16
+export 'package:photo/src/delegate/sort_delegate.dart';
13 17
 
14 18
 class PhotoPicker {
15 19
   static PhotoPicker _instance;
@@ -53,6 +57,7 @@ class PhotoPicker {
53 57
     Color disableColor,
54 58
     int thumbSize = 64,
55 59
     I18nProvider provider = I18nProvider.chinese,
60
+    SortDelegate sortDelegate,
56 61
   }) {
57 62
     assert(provider != null, "provider must be not null");
58 63
     assert(context != null, "context must be not null");
@@ -62,6 +67,8 @@ class PhotoPicker {
62 67
     disableColor ??= Theme.of(context)?.disabledColor ?? Colors.grey;
63 68
     textColor ??= Colors.white;
64 69
 
70
+    sortDelegate ??= SortDelegate.common;
71
+
65 72
     var options = Options(
66 73
       rowCount: rowCount,
67 74
       dividerColor: dividerColor,
@@ -72,9 +79,14 @@ class PhotoPicker {
72 79
       textColor: textColor,
73 80
       themeColor: themeColor,
74 81
       thumbSize: thumbSize,
82
+      sortDelegate: sortDelegate,
75 83
     );
76 84
 
77
-    return PhotoPicker()._pickImage(context, options, provider);
85
+    return PhotoPicker()._pickImage(
86
+      context,
87
+      options,
88
+      provider,
89
+    );
78 90
   }
79 91
 
80 92
   Future<List<ImageEntity>> _pickImage(
@@ -100,13 +112,13 @@ class PhotoPicker {
100 112
   }
101 113
 
102 114
   Future<List<ImageEntity>> _openGalleryContentPage(
103
-      BuildContext context, Options options, I18nProvider provider)async{
115
+      BuildContext context, Options options, I18nProvider provider) async {
104 116
     return Navigator.of(context).push(
105 117
       MaterialPageRoute(
106 118
         builder: (ctx) => PhotoApp(
107
-          options: options,
108
-          provider: provider,
109
-        ),
119
+              options: options,
120
+              provider: provider,
121
+            ),
110 122
       ),
111 123
     );
112 124
   }

+ 66
- 0
lib/src/delegate/sort_delegate.dart Ver arquivo

@@ -0,0 +1,66 @@
1
+import 'package:photo_manager/photo_manager.dart';
2
+
3
+abstract class SortDelegate {
4
+  const SortDelegate();
5
+
6
+  void sort(List<ImagePathEntity> list);
7
+
8
+  static const none = DefaultSortDelegate();
9
+
10
+  static const common = CommonSortDelegate();
11
+}
12
+
13
+class DefaultSortDelegate extends SortDelegate {
14
+  const DefaultSortDelegate();
15
+
16
+  @override
17
+  void sort(List<ImagePathEntity> list) {}
18
+}
19
+
20
+class CommonSortDelegate extends SortDelegate {
21
+  const CommonSortDelegate();
22
+
23
+  @override
24
+  void sort(List<ImagePathEntity> list) {
25
+    list.sort((path1, path2) {
26
+      if (path1 == ImagePathEntity.all) {
27
+        return -1;
28
+      }
29
+
30
+      if (path2 == ImagePathEntity.all) {
31
+        return 1;
32
+      }
33
+
34
+      if (_isCamera(path1)) {
35
+        return -1;
36
+      }
37
+
38
+      if (_isCamera(path2)) {
39
+        return 1;
40
+      }
41
+
42
+      if (_isScreenShot(path1)) {
43
+        return -1;
44
+      }
45
+
46
+      if (_isScreenShot(path2)) {
47
+        return 1;
48
+      }
49
+
50
+      return otherSort(path1, path2);
51
+    });
52
+  }
53
+
54
+  int otherSort(ImagePathEntity path1, ImagePathEntity path2) {
55
+    return path1.name.compareTo(path2.name);
56
+  }
57
+
58
+  bool _isCamera(ImagePathEntity entity) {
59
+    return entity.name.toUpperCase() == "camera".toUpperCase();
60
+  }
61
+
62
+  bool _isScreenShot(ImagePathEntity entity) {
63
+    return entity.name.toUpperCase() == "screenshots".toUpperCase() ||
64
+        entity.name.toUpperCase() == "screenshot".toUpperCase();
65
+  }
66
+}

+ 23
- 5
lib/src/engine/lru_cache.dart Ver arquivo

@@ -4,17 +4,35 @@ import 'dart:typed_data';
4 4
 import 'package:photo_manager/photo_manager.dart';
5 5
 
6 6
 class ImageLruCache {
7
-  static LRUMap<ImageEntity, Uint8List> _map = LRUMap(500);
7
+  static LRUMap<_ImageCacheEntity, Uint8List> _map = LRUMap(500);
8 8
 
9
-  static Uint8List getData(ImageEntity entity) {
10
-    return _map.get(entity);
9
+  static Uint8List getData(ImageEntity entity, [int size = 64]) {
10
+    return _map.get(_ImageCacheEntity(entity, size));
11 11
   }
12 12
 
13
-  static void setData(ImageEntity entity, Uint8List list) {
14
-    _map.put(entity, list);
13
+  static void setData(ImageEntity entity, int size, Uint8List list) {
14
+    _map.put(_ImageCacheEntity(entity,size), list);
15 15
   }
16 16
 }
17 17
 
18
+class _ImageCacheEntity {
19
+  ImageEntity entity;
20
+  int size;
21
+
22
+  _ImageCacheEntity(this.entity, this.size);
23
+
24
+  @override
25
+  bool operator ==(Object other) =>
26
+      identical(this, other) ||
27
+      other is _ImageCacheEntity &&
28
+          runtimeType == other.runtimeType &&
29
+          entity == other.entity &&
30
+          size == other.size;
31
+
32
+  @override
33
+  int get hashCode => entity.hashCode ^ size.hashCode;
34
+}
35
+
18 36
 // Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
19 37
 // for details. All rights reserved. Use of this source code is governed by a
20 38
 // BSD-style license that can be found in the LICENSE file.

+ 4
- 0
lib/src/entity/options.dart Ver arquivo

@@ -1,4 +1,5 @@
1 1
 import 'package:flutter/material.dart';
2
+import 'package:photo/src/delegate/sort_delegate.dart';
2 3
 
3 4
 class Options {
4 5
   final int rowCount;
@@ -19,6 +20,8 @@ class Options {
19 20
 
20 21
   final int thumbSize;
21 22
 
23
+  final SortDelegate sortDelegate;
24
+
22 25
   const Options({
23 26
     this.rowCount,
24 27
     this.maxSelected,
@@ -29,5 +32,6 @@ class Options {
29 32
     this.textColor,
30 33
     this.disableColor,
31 34
     this.thumbSize,
35
+    this.sortDelegate,
32 36
   });
33 37
 }

+ 9
- 0
lib/src/provider/i18n_provider.dart Ver arquivo

@@ -16,6 +16,10 @@ abstract class I18nProvider {
16 16
 
17 17
   String getAllGalleryText(Options options);
18 18
 
19
+  String loadingText(){
20
+    return "loading...";
21
+  }
22
+
19 23
   I18NPermissionProvider getNotPermissionText(Options options);
20 24
 
21 25
   static const I18nProvider chinese = CNProvider();
@@ -56,6 +60,11 @@ class CNProvider extends I18nProvider {
56 60
     return "全部图片";
57 61
   }
58 62
 
63
+  @override
64
+  String loadingText() {
65
+    return "加载中...";
66
+  }
67
+
59 68
   @override
60 69
   I18NPermissionProvider getNotPermissionText(Options options) {
61 70
     return I18NPermissionProvider(

+ 42
- 3
lib/src/ui/page/photo_main_page.dart Ver arquivo

@@ -35,6 +35,8 @@ class _PhotoMainPageState extends State<PhotoMainPage>
35 35
 
36 36
   ImagePathEntity _currentPath = ImagePathEntity.all;
37 37
 
38
+  bool _isInit = false;
39
+
38 40
   ImagePathEntity get currentPath {
39 41
     if (_currentPath == null) {
40 42
       return null;
@@ -150,16 +152,25 @@ class _PhotoMainPageState extends State<PhotoMainPage>
150 152
 
151 153
   void _refreshList() async {
152 154
     var pathList = await PhotoManager.getImagePathList();
155
+
156
+    options.sortDelegate.sort(pathList);
157
+
153 158
     galleryPathList.clear();
154 159
     galleryPathList.addAll(pathList);
155 160
 
156 161
     var imageList = await currentPath.imageList;
157 162
     this.list.clear();
158 163
     this.list.addAll(imageList);
159
-    setState(() {});
164
+    setState(() {
165
+      _isInit = true;
166
+    });
160 167
   }
161 168
 
162 169
   Widget _buildBody() {
170
+    if (!_isInit) {
171
+      return _buildLoading();
172
+    }
173
+
163 174
     return Container(
164 175
       color: options.disableColor,
165 176
       child: GridView.builder(
@@ -341,6 +352,34 @@ class _PhotoMainPageState extends State<PhotoMainPage>
341 352
     }
342 353
     return false;
343 354
   }
355
+
356
+  Widget _buildLoading() {
357
+    return Center(
358
+      child: Column(
359
+        children: <Widget>[
360
+          Container(
361
+            width: 40.0,
362
+            height: 40.0,
363
+            padding: const EdgeInsets.all(5.0),
364
+            child: CircularProgressIndicator(
365
+              valueColor: AlwaysStoppedAnimation(themeColor),
366
+            ),
367
+          ),
368
+          Padding(
369
+            padding: const EdgeInsets.all(8.0),
370
+            child: Text(
371
+              i18nProvider.loadingText(),
372
+              style: const TextStyle(
373
+                fontSize: 12.0,
374
+              ),
375
+            ),
376
+          ),
377
+        ],
378
+        crossAxisAlignment: CrossAxisAlignment.center,
379
+        mainAxisAlignment: MainAxisAlignment.center,
380
+      ),
381
+    );
382
+  }
344 383
 }
345 384
 
346 385
 class _BottomWidget extends StatefulWidget {
@@ -457,7 +496,7 @@ class ImageItem extends StatelessWidget {
457 496
 
458 497
   @override
459 498
   Widget build(BuildContext context) {
460
-    var thumb = ImageLruCache.getData(entity);
499
+    var thumb = ImageLruCache.getData(entity, size);
461 500
     if (thumb != null) {
462 501
       return _buildImageItem(thumb);
463 502
     }
@@ -468,7 +507,7 @@ class ImageItem extends StatelessWidget {
468 507
         var futureData = snapshot.data;
469 508
         if (snapshot.connectionState == ConnectionState.done &&
470 509
             futureData != null) {
471
-          ImageLruCache.setData(entity, futureData);
510
+          ImageLruCache.setData(entity, size, futureData);
472 511
           return _buildImageItem(futureData);
473 512
         }
474 513
         return Center(

+ 1
- 1
pubspec.yaml Ver arquivo

@@ -1,6 +1,6 @@
1 1
 name: photo
2 2
 description: image picker, multi picker,use flutter as ui, if you want to build custom ui,you just use photo_manager.
3
-version: 0.0.4
3
+version: 0.0.5
4 4
 author: caijinglong<cjl_spy@163.com>
5 5
 homepage: https://github.com/CaiJingLong/flutter_photo
6 6