Browse Source

Merge pull request #32 from CaiJingLong/auto-refresh

Auto refresh when the asset changes
C 5 years ago
parent
commit
2624e393a0
No account linked to committer's email address

+ 8
- 1
CHANGELOG.md View File

1
 # CHANGELOG
1
 # CHANGELOG
2
 
2
 
3
-## [0.2.1] add params photoList
3
+## [0.3.0] add params photoList
4
+
5
+**Breaking change**. Migrate from the deprecated original Android Support Library to AndroidX. This shouldn't result in any functional changes, but it requires any Android apps using this plugin to also migrate if they're using the original support library.
6
+
7
+fix:
8
+
9
+- duration badge
10
+- sort image
4
 
11
 
5
 ## [0.2.0]
12
 ## [0.2.0]
6
 
13
 

+ 102
- 0
lib/src/ui/page/main/bottom_widget.dart View File

1
+
2
+part of '../photo_main_page.dart';
3
+
4
+class _BottomWidget extends StatefulWidget {
5
+  final ValueChanged<AssetPathEntity> onGalleryChange;
6
+
7
+  final Options options;
8
+
9
+  final I18nProvider provider;
10
+
11
+  final SelectedProvider selectedProvider;
12
+
13
+  final String galleryName;
14
+
15
+  final GalleryListProvider galleryListProvider;
16
+  final VoidCallback onTapPreview;
17
+
18
+  const _BottomWidget({
19
+    Key key,
20
+    this.onGalleryChange,
21
+    this.options,
22
+    this.provider,
23
+    this.selectedProvider,
24
+    this.galleryName = "",
25
+    this.galleryListProvider,
26
+    this.onTapPreview,
27
+  }) : super(key: key);
28
+
29
+  @override
30
+  __BottomWidgetState createState() => __BottomWidgetState();
31
+}
32
+
33
+class __BottomWidgetState extends State<_BottomWidget> {
34
+  Options get options => widget.options;
35
+
36
+  I18nProvider get i18nProvider => widget.provider;
37
+
38
+  @override
39
+  Widget build(BuildContext context) {
40
+    var textStyle = TextStyle(fontSize: 14.0);
41
+    const textPadding = const EdgeInsets.symmetric(horizontal: 16.0);
42
+    return Container(
43
+      color: options.themeColor,
44
+      child: SafeArea(
45
+        bottom: true,
46
+        top: false,
47
+        child: Container(
48
+          height: 52.0,
49
+          child: Row(
50
+            children: <Widget>[
51
+              FlatButton(
52
+                onPressed: _showGallerySelectDialog,
53
+                splashColor: Colors.transparent,
54
+                child: Container(
55
+                  alignment: Alignment.center,
56
+                  height: 44.0,
57
+                  padding: textPadding,
58
+                  child: Text(
59
+                    widget.galleryName,
60
+                    style: textStyle.copyWith(color: options.textColor),
61
+                  ),
62
+                ),
63
+              ),
64
+              Expanded(
65
+                child: Container(),
66
+              ),
67
+              FlatButton(
68
+                onPressed: widget.onTapPreview,
69
+                textColor: options.textColor,
70
+                splashColor: Colors.transparent,
71
+                disabledTextColor: options.disableColor,
72
+                child: Container(
73
+                  height: 44.0,
74
+                  alignment: Alignment.center,
75
+                  child: Text(
76
+                    i18nProvider.getPreviewText(
77
+                        options, widget.selectedProvider),
78
+                    style: textStyle,
79
+                  ),
80
+                  padding: textPadding,
81
+                ),
82
+              ),
83
+            ],
84
+          ),
85
+        ),
86
+      ),
87
+    );
88
+  }
89
+
90
+  void _showGallerySelectDialog() async {
91
+    var result = await showModalBottomSheet(
92
+      context: context,
93
+      builder: (ctx) => ChangeGalleryDialog(
94
+            galleryList: widget.galleryListProvider.galleryPathList,
95
+            i18n: i18nProvider,
96
+            options: options,
97
+          ),
98
+    );
99
+
100
+    if (result != null) widget.onGalleryChange?.call(result);
101
+  }
102
+}

+ 85
- 0
lib/src/ui/page/main/image_item.dart View File

1
+part of '../photo_main_page.dart';
2
+
3
+
4
+class ImageItem extends StatelessWidget {
5
+  final AssetEntity entity;
6
+
7
+  final Color themeColor;
8
+
9
+  final int size;
10
+
11
+  final LoadingDelegate loadingDelegate;
12
+
13
+  final BadgeDelegate badgeDelegate;
14
+
15
+  const ImageItem({
16
+    Key key,
17
+    this.entity,
18
+    this.themeColor,
19
+    this.size = 64,
20
+    this.loadingDelegate,
21
+    this.badgeDelegate,
22
+  }) : super(key: key);
23
+
24
+  @override
25
+  Widget build(BuildContext context) {
26
+    var thumb = ImageLruCache.getData(entity, size);
27
+    if (thumb != null) {
28
+      return _buildImageItem(context, thumb);
29
+    }
30
+
31
+    return FutureBuilder<Uint8List>(
32
+      future: entity.thumbDataWithSize(size, size),
33
+      builder: (BuildContext context, AsyncSnapshot<Uint8List> snapshot) {
34
+        var futureData = snapshot.data;
35
+        if (snapshot.connectionState == ConnectionState.done &&
36
+            futureData != null) {
37
+          ImageLruCache.setData(entity, size, futureData);
38
+          return _buildImageItem(context, futureData);
39
+        }
40
+        return Center(
41
+          child: loadingDelegate.buildPreviewLoading(
42
+            context,
43
+            entity,
44
+            themeColor,
45
+          ),
46
+        );
47
+      },
48
+    );
49
+  }
50
+
51
+  Widget _buildImageItem(BuildContext context, Uint8List data) {
52
+    var image = Image.memory(
53
+      data,
54
+      width: double.infinity,
55
+      height: double.infinity,
56
+      fit: BoxFit.cover,
57
+    );
58
+    // FutureBuilder()
59
+    var badge = FutureBuilder<Duration>(
60
+      future: entity.videoDuration,
61
+      builder: (ctx, snapshot) {
62
+        if (snapshot.hasData && snapshot != null) {
63
+          var buildBadge =
64
+              badgeDelegate?.buildBadge(context, entity.type, snapshot.data);
65
+          if (buildBadge == null) {
66
+            return Container();
67
+          } else {
68
+            return buildBadge;
69
+          }
70
+        } else {
71
+          return Container();
72
+        }
73
+      },
74
+    );
75
+
76
+    return Stack(
77
+      children: <Widget>[
78
+        image,
79
+        IgnorePointer(
80
+          child: badge,
81
+        ),
82
+      ],
83
+    );
84
+  }
85
+}

+ 14
- 181
lib/src/ui/page/photo_main_page.dart View File

14
 import 'package:photo/src/ui/page/photo_preview_page.dart';
14
 import 'package:photo/src/ui/page/photo_preview_page.dart';
15
 import 'package:photo_manager/photo_manager.dart';
15
 import 'package:photo_manager/photo_manager.dart';
16
 
16
 
17
+part './main/bottom_widget.dart';
18
+part './main/image_item.dart';
19
+
17
 class PhotoMainPage extends StatefulWidget {
20
 class PhotoMainPage extends StatefulWidget {
18
   final ValueChanged<List<AssetEntity>> onClose;
21
   final ValueChanged<List<AssetEntity>> onClose;
19
   final Options options;
22
   final Options options;
67
 
70
 
68
   bool isPushed = false;
71
   bool isPushed = false;
69
 
72
 
73
+  bool get useAlbum => widget.photoList == null || widget.photoList.isEmpty;
74
+
70
   @override
75
   @override
71
   void initState() {
76
   void initState() {
72
     super.initState();
77
     super.initState();
73
     _refreshList();
78
     _refreshList();
74
     scaffoldKey = GlobalKey();
79
     scaffoldKey = GlobalKey();
75
     scrollController = ScrollController();
80
     scrollController = ScrollController();
81
+    PhotoManager.addChangeCallback(_onAssetChange);
82
+    PhotoManager.startChangeNotify();
76
   }
83
   }
77
 
84
 
78
   @override
85
   @override
79
   void dispose() {
86
   void dispose() {
87
+    PhotoManager.removeChangeCallback(_onAssetChange);
88
+    PhotoManager.stopChangeNotify();
80
     scaffoldKey = null;
89
     scaffoldKey = null;
81
     super.dispose();
90
     super.dispose();
82
   }
91
   }
165
   }
174
   }
166
 
175
 
167
   void _refreshList() {
176
   void _refreshList() {
168
-    if (widget.photoList != null && widget.photoList.isNotEmpty) {
177
+    if (!useAlbum) {
169
       _refreshListFromWidget();
178
       _refreshListFromWidget();
170
       return;
179
       return;
171
     }
180
     }
448
       ),
457
       ),
449
     );
458
     );
450
   }
459
   }
451
-}
452
-
453
-class _BottomWidget extends StatefulWidget {
454
-  final ValueChanged<AssetPathEntity> onGalleryChange;
455
-
456
-  final Options options;
457
-
458
-  final I18nProvider provider;
459
-
460
-  final SelectedProvider selectedProvider;
461
-
462
-  final String galleryName;
463
-
464
-  final GalleryListProvider galleryListProvider;
465
-  final VoidCallback onTapPreview;
466
-
467
-  const _BottomWidget({
468
-    Key key,
469
-    this.onGalleryChange,
470
-    this.options,
471
-    this.provider,
472
-    this.selectedProvider,
473
-    this.galleryName = "",
474
-    this.galleryListProvider,
475
-    this.onTapPreview,
476
-  }) : super(key: key);
477
-
478
-  @override
479
-  __BottomWidgetState createState() => __BottomWidgetState();
480
-}
481
-
482
-class __BottomWidgetState extends State<_BottomWidget> {
483
-  Options get options => widget.options;
484
-
485
-  I18nProvider get i18nProvider => widget.provider;
486
-
487
-  @override
488
-  Widget build(BuildContext context) {
489
-    var textStyle = TextStyle(fontSize: 14.0);
490
-    const textPadding = const EdgeInsets.symmetric(horizontal: 16.0);
491
-    return Container(
492
-      color: options.themeColor,
493
-      child: SafeArea(
494
-        bottom: true,
495
-        top: false,
496
-        child: Container(
497
-          height: 52.0,
498
-          child: Row(
499
-            children: <Widget>[
500
-              FlatButton(
501
-                onPressed: _showGallerySelectDialog,
502
-                splashColor: Colors.transparent,
503
-                child: Container(
504
-                  alignment: Alignment.center,
505
-                  height: 44.0,
506
-                  padding: textPadding,
507
-                  child: Text(
508
-                    widget.galleryName,
509
-                    style: textStyle.copyWith(color: options.textColor),
510
-                  ),
511
-                ),
512
-              ),
513
-              Expanded(
514
-                child: Container(),
515
-              ),
516
-              FlatButton(
517
-                onPressed: widget.onTapPreview,
518
-                textColor: options.textColor,
519
-                splashColor: Colors.transparent,
520
-                disabledTextColor: options.disableColor,
521
-                child: Container(
522
-                  height: 44.0,
523
-                  alignment: Alignment.center,
524
-                  child: Text(
525
-                    i18nProvider.getPreviewText(
526
-                        options, widget.selectedProvider),
527
-                    style: textStyle,
528
-                  ),
529
-                  padding: textPadding,
530
-                ),
531
-              ),
532
-            ],
533
-          ),
534
-        ),
535
-      ),
536
-    );
537
-  }
538
-
539
-  void _showGallerySelectDialog() async {
540
-    var result = await showModalBottomSheet(
541
-      context: context,
542
-      builder: (ctx) => ChangeGalleryDialog(
543
-            galleryList: widget.galleryListProvider.galleryPathList,
544
-            i18n: i18nProvider,
545
-            options: options,
546
-          ),
547
-    );
548
-
549
-    if (result != null) widget.onGalleryChange?.call(result);
550
-  }
551
-}
552
-
553
-class ImageItem extends StatelessWidget {
554
-  final AssetEntity entity;
555
-
556
-  final Color themeColor;
557
-
558
-  final int size;
559
-
560
-  final LoadingDelegate loadingDelegate;
561
 
460
 
562
-  final BadgeDelegate badgeDelegate;
563
-
564
-  const ImageItem({
565
-    Key key,
566
-    this.entity,
567
-    this.themeColor,
568
-    this.size = 64,
569
-    this.loadingDelegate,
570
-    this.badgeDelegate,
571
-  }) : super(key: key);
572
-
573
-  @override
574
-  Widget build(BuildContext context) {
575
-    var thumb = ImageLruCache.getData(entity, size);
576
-    if (thumb != null) {
577
-      return _buildImageItem(context, thumb);
461
+  void _onAssetChange() {
462
+    if (useAlbum) {
463
+      _refreshList();
578
     }
464
     }
579
-
580
-    return FutureBuilder<Uint8List>(
581
-      future: entity.thumbDataWithSize(size, size),
582
-      builder: (BuildContext context, AsyncSnapshot<Uint8List> snapshot) {
583
-        var futureData = snapshot.data;
584
-        if (snapshot.connectionState == ConnectionState.done &&
585
-            futureData != null) {
586
-          ImageLruCache.setData(entity, size, futureData);
587
-          return _buildImageItem(context, futureData);
588
-        }
589
-        return Center(
590
-          child: loadingDelegate.buildPreviewLoading(
591
-            context,
592
-            entity,
593
-            themeColor,
594
-          ),
595
-        );
596
-      },
597
-    );
598
-  }
599
-
600
-  Widget _buildImageItem(BuildContext context, Uint8List data) {
601
-    var image = Image.memory(
602
-      data,
603
-      width: double.infinity,
604
-      height: double.infinity,
605
-      fit: BoxFit.cover,
606
-    );
607
-    // FutureBuilder()
608
-    var badge = FutureBuilder<Duration>(
609
-      future: entity.videoDuration,
610
-      builder: (ctx, snapshot) {
611
-        if (snapshot.hasData && snapshot != null) {
612
-          var buildBadge =
613
-              badgeDelegate?.buildBadge(context, entity.type, snapshot.data);
614
-          if (buildBadge == null) {
615
-            return Container();
616
-          } else {
617
-            return buildBadge;
618
-          }
619
-        } else {
620
-          return Container();
621
-        }
622
-      },
623
-    );
624
-
625
-    return Stack(
626
-      children: <Widget>[
627
-        image,
628
-        IgnorePointer(
629
-          child: badge,
630
-        ),
631
-      ],
632
-    );
633
   }
465
   }
466
+  
634
 }
467
 }

+ 1
- 1
pubspec.yaml View File

1
 name: photo
1
 name: photo
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.
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.2.1
3
+version: 0.3.0
4
 author: caijinglong<cjl_spy@163.com>
4
 author: caijinglong<cjl_spy@163.com>
5
 homepage: https://github.com/CaiJingLong/flutter_photo
5
 homepage: https://github.com/CaiJingLong/flutter_photo
6
 
6