Parcourir la source

Merge pull request #32 from CaiJingLong/auto-refresh

Auto refresh when the asset changes
C il y a 5 ans
Parent
révision
2624e393a0
No account linked to committer's email address

+ 8
- 1
CHANGELOG.md Voir le fichier

@@ -1,6 +1,13 @@
1 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 12
 ## [0.2.0]
6 13
 

+ 102
- 0
lib/src/ui/page/main/bottom_widget.dart Voir le fichier

@@ -0,0 +1,102 @@
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 Voir le fichier

@@ -0,0 +1,85 @@
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 Voir le fichier

@@ -14,6 +14,9 @@ import 'package:photo/src/ui/dialog/change_gallery_dialog.dart';
14 14
 import 'package:photo/src/ui/page/photo_preview_page.dart';
15 15
 import 'package:photo_manager/photo_manager.dart';
16 16
 
17
+part './main/bottom_widget.dart';
18
+part './main/image_item.dart';
19
+
17 20
 class PhotoMainPage extends StatefulWidget {
18 21
   final ValueChanged<List<AssetEntity>> onClose;
19 22
   final Options options;
@@ -67,16 +70,22 @@ class _PhotoMainPageState extends State<PhotoMainPage>
67 70
 
68 71
   bool isPushed = false;
69 72
 
73
+  bool get useAlbum => widget.photoList == null || widget.photoList.isEmpty;
74
+
70 75
   @override
71 76
   void initState() {
72 77
     super.initState();
73 78
     _refreshList();
74 79
     scaffoldKey = GlobalKey();
75 80
     scrollController = ScrollController();
81
+    PhotoManager.addChangeCallback(_onAssetChange);
82
+    PhotoManager.startChangeNotify();
76 83
   }
77 84
 
78 85
   @override
79 86
   void dispose() {
87
+    PhotoManager.removeChangeCallback(_onAssetChange);
88
+    PhotoManager.stopChangeNotify();
80 89
     scaffoldKey = null;
81 90
     super.dispose();
82 91
   }
@@ -165,7 +174,7 @@ class _PhotoMainPageState extends State<PhotoMainPage>
165 174
   }
166 175
 
167 176
   void _refreshList() {
168
-    if (widget.photoList != null && widget.photoList.isNotEmpty) {
177
+    if (!useAlbum) {
169 178
       _refreshListFromWidget();
170 179
       return;
171 180
     }
@@ -448,187 +457,11 @@ class _PhotoMainPageState extends State<PhotoMainPage>
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 Voir le fichier

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