Selaa lähdekoodia

选择相册修改完毕

Caijinglong 6 vuotta sitten
vanhempi
commit
82b3fcc973

+ 2
- 2
lib/photo.dart Näytä tiedosto

@@ -4,9 +4,9 @@ import 'package:flutter/material.dart';
4 4
 import 'dart:async';
5 5
 
6 6
 import 'package:photo/src/entity/options.dart';
7
-import 'package:photo/src/page/not_permission_dialog.dart';
8
-import 'package:photo/src/page/photo_main_page.dart';
9 7
 import 'package:photo/src/provider/i18n_provider.dart';
8
+import 'package:photo/src/ui/dialog/not_permission_dialog.dart';
9
+import 'package:photo/src/ui/page/photo_main_page.dart';
10 10
 import 'package:photo_manager/photo_manager.dart';
11 11
 
12 12
 /// A Calculator.

+ 5
- 0
lib/src/provider/gallery_list_provider.dart Näytä tiedosto

@@ -0,0 +1,5 @@
1
+import 'package:photo_manager/photo_manager.dart';
2
+
3
+abstract class GalleryListProvider {
4
+  List<ImagePathEntity> galleryPathList = [];
5
+}

+ 25
- 3
lib/src/provider/selected_provider.dart Näytä tiedosto

@@ -1,12 +1,34 @@
1 1
 import 'package:photo_manager/photo_manager.dart';
2 2
 
3 3
 abstract class SelectedProvider {
4
+  List<ImageEntity> selectedList = [];
4 5
 
5
-  int get selectedCount;
6
+  int get selectedCount => selectedList.length;
6 7
 
7
-  bool containsEntity(ImageEntity entity);
8
+  bool containsEntity(ImageEntity entity) {
9
+    return selectedList.contains(entity);
10
+  }
8 11
 
9
-  int indexOfSelected(ImageEntity entity);
12
+  int indexOfSelected(ImageEntity entity) {
13
+    return selectedList.indexOf(entity);
14
+  }
15
+
16
+  bool isUpperLimit();
17
+
18
+  bool addSelectEntity(ImageEntity entity) {
19
+    if (containsEntity(entity)) {
20
+      return false;
21
+    }
22
+    if (isUpperLimit() == true) {
23
+      return false;
24
+    }
25
+    selectedList.add(entity);
26
+    return true;
27
+  }
28
+
29
+  bool removeSelectEntity(ImageEntity entity) {
30
+    return selectedList.remove(entity);
31
+  }
10 32
 
11 33
   void sure();
12 34
 }

+ 35
- 0
lib/src/ui/dialog/change_gallery_dialog.dart Näytä tiedosto

@@ -0,0 +1,35 @@
1
+import 'package:flutter/material.dart';
2
+import 'package:photo_manager/photo_manager.dart';
3
+
4
+class ChangeGalleryDialog extends StatefulWidget {
5
+  final List<ImagePathEntity> galleryList;
6
+
7
+  const ChangeGalleryDialog({Key key, this.galleryList}) : super(key: key);
8
+
9
+  @override
10
+  _ChangeGalleryDialogState createState() => _ChangeGalleryDialogState();
11
+}
12
+
13
+class _ChangeGalleryDialogState extends State<ChangeGalleryDialog> {
14
+  @override
15
+  Widget build(BuildContext context) {
16
+    return Container(
17
+      child: ListView.builder(
18
+        itemBuilder: _buildItem,
19
+        itemCount: widget.galleryList.length,
20
+      ),
21
+    );
22
+  }
23
+
24
+  Widget _buildItem(BuildContext context, int index) {
25
+    var entity = widget.galleryList[index];
26
+    return FlatButton(
27
+      child: ListTile(
28
+        title: Text(entity.name),
29
+      ),
30
+      onPressed: () {
31
+        Navigator.pop(context, entity);
32
+      },
33
+    );
34
+  }
35
+}

lib/src/page/not_permission_dialog.dart → lib/src/ui/dialog/not_permission_dialog.dart Näytä tiedosto


lib/src/page/photo_main_page.dart → lib/src/ui/page/photo_main_page.dart Näytä tiedosto

@@ -3,8 +3,10 @@ import 'dart:typed_data';
3 3
 import 'package:flutter/material.dart';
4 4
 import 'package:photo/src/engine/lru_cache.dart';
5 5
 import 'package:photo/src/entity/options.dart';
6
+import 'package:photo/src/provider/gallery_list_provider.dart';
6 7
 import 'package:photo/src/provider/i18n_provider.dart';
7 8
 import 'package:photo/src/provider/selected_provider.dart';
9
+import 'package:photo/src/ui/dialog/change_gallery_dialog.dart';
8 10
 import 'package:photo_manager/photo_manager.dart';
9 11
 
10 12
 class PhotoMainPage extends StatefulWidget {
@@ -17,35 +19,44 @@ class PhotoMainPage extends StatefulWidget {
17 19
   _PhotoMainPageState createState() => _PhotoMainPageState();
18 20
 }
19 21
 
20
-class _PhotoMainPageState extends State<PhotoMainPage> with SelectedProvider {
22
+class _PhotoMainPageState extends State<PhotoMainPage>
23
+    with SelectedProvider, GalleryListProvider {
21 24
   Options get options => widget.options;
22 25
 
23 26
   I18nProvider get i18nProvider => widget.provider;
24 27
 
25
-  List<ImageEntity> selectedList = [];
26
-  List<ImageParentPath> pathList = [];
27
-
28 28
   List<ImageEntity> list = [];
29 29
 
30 30
   Color get themeColor => options.themeColor;
31 31
 
32
-  ImageParentPath _currentPath;
32
+  ImagePathEntity _currentPath = ImagePathEntity.all;
33 33
 
34
-  ImageParentPath get currentPath {
34
+  ImagePathEntity get currentPath {
35 35
     if (_currentPath == null) {
36 36
       return null;
37 37
     }
38 38
     return _currentPath;
39 39
   }
40 40
 
41
-  set currentPath(ImageParentPath value) {
41
+  set currentPath(ImagePathEntity value) {
42 42
     _currentPath = value;
43 43
   }
44 44
 
45
+  GlobalKey scaffoldKey;
46
+  ScrollController scrollController;
47
+
45 48
   @override
46 49
   void initState() {
47 50
     super.initState();
48 51
     _refreshList();
52
+    scaffoldKey = GlobalKey();
53
+    scrollController = ScrollController();
54
+  }
55
+
56
+  @override
57
+  void dispose() {
58
+    scaffoldKey = null;
59
+    super.dispose();
49 60
   }
50 61
 
51 62
   @override
@@ -77,10 +88,13 @@ class _PhotoMainPageState extends State<PhotoMainPage> with SelectedProvider {
77 88
           ),
78 89
           body: _buildBody(),
79 90
           bottomNavigationBar: _BottomWidget(
91
+            key: scaffoldKey,
80 92
             provider: i18nProvider,
81 93
             options: options,
94
+            galleryName: currentPath.name,
82 95
             onGalleryChange: _onGalleryChange,
83 96
             selectedProvider: this,
97
+            galleryListProvider: this,
84 98
           ),
85 99
         ),
86 100
       ),
@@ -92,10 +106,39 @@ class _PhotoMainPageState extends State<PhotoMainPage> with SelectedProvider {
92 106
     );
93 107
   }
94 108
 
109
+  @override
110
+  bool isUpperLimit() {
111
+    var result = selectedCount == options.maxSelected;
112
+    if (result) _showTip(i18nProvider.getMaxTipText(options));
113
+    return result;
114
+  }
115
+
116
+  void sure() {
117
+    Navigator.pop(context, selectedList);
118
+  }
119
+
120
+  void _showTip(String msg) {
121
+    Scaffold.of(scaffoldKey.currentContext).showSnackBar(
122
+      SnackBar(
123
+        content: Text(
124
+          msg,
125
+          style: TextStyle(
126
+            color: options.textColor,
127
+            fontSize: 14.0,
128
+          ),
129
+        ),
130
+        duration: Duration(milliseconds: 1500),
131
+        backgroundColor: themeColor.withOpacity(0.7),
132
+      ),
133
+    );
134
+  }
135
+
95 136
   void _refreshList() async {
96
-    pathList = await ImageScanner.getImagePathList();
97
-    var path = pathList[0];
98
-    var imageList = await path.imageList;
137
+    var pathList = await ImageScanner.getImagePathList();
138
+    galleryPathList.clear();
139
+    galleryPathList.addAll(pathList);
140
+
141
+    var imageList = await currentPath.imageList;
99 142
     this.list.clear();
100 143
     this.list.addAll(imageList);
101 144
     print(list);
@@ -106,6 +149,7 @@ class _PhotoMainPageState extends State<PhotoMainPage> with SelectedProvider {
106 149
     return Container(
107 150
       color: options.disableColor,
108 151
       child: GridView.builder(
152
+        controller: scrollController,
109 153
         gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
110 154
           crossAxisCount: options.rowCount,
111 155
           childAspectRatio: options.itemRadio,
@@ -118,19 +162,6 @@ class _PhotoMainPageState extends State<PhotoMainPage> with SelectedProvider {
118 162
     );
119 163
   }
120 164
 
121
-  @override
122
-  int get selectedCount => selectedList.length;
123
-
124
-  @override
125
-  bool containsEntity(ImageEntity entity) {
126
-    return selectedList.contains(entity);
127
-  }
128
-
129
-  @override
130
-  int indexOfSelected(ImageEntity entity) {
131
-    return selectedList.indexOf(entity);
132
-  }
133
-
134 165
   Widget _buildItem(BuildContext context, int index) {
135 166
     var data = list[index];
136 167
     return GestureDetector(
@@ -208,24 +239,29 @@ class _PhotoMainPageState extends State<PhotoMainPage> with SelectedProvider {
208 239
 
209 240
   void changeCheck(bool value, ImageEntity entity) {
210 241
     if (value) {
211
-      selectedList.add(entity);
242
+      addSelectEntity(entity);
212 243
     } else {
213
-      selectedList.remove(entity);
244
+      removeSelectEntity(entity);
214 245
     }
215 246
     setState(() {});
216 247
   }
217 248
 
218
-  void sure() {
219
-    Navigator.pop(context, selectedList);
220
-  }
221
-
222 249
   void _onItemClick(ImageEntity data) {}
223 250
 
224
-  void _onGalleryChange(ImageParentPath value) {}
251
+  void _onGalleryChange(ImagePathEntity value) {
252
+    _currentPath = value;
253
+
254
+    _currentPath.imageList.then((v) {
255
+      list.clear();
256
+      list.addAll(v);
257
+      scrollController.jumpTo(0.0);
258
+      setState(() {});
259
+    });
260
+  }
225 261
 }
226 262
 
227 263
 class _BottomWidget extends StatefulWidget {
228
-  final ValueChanged<ImageParentPath> onGalleryChange;
264
+  final ValueChanged<ImagePathEntity> onGalleryChange;
229 265
 
230 266
   final Options options;
231 267
 
@@ -235,6 +271,8 @@ class _BottomWidget extends StatefulWidget {
235 271
 
236 272
   final String galleryName;
237 273
 
274
+  final GalleryListProvider galleryListProvider;
275
+
238 276
   const _BottomWidget({
239 277
     Key key,
240 278
     this.onGalleryChange,
@@ -242,6 +280,7 @@ class _BottomWidget extends StatefulWidget {
242 280
     this.provider,
243 281
     this.selectedProvider,
244 282
     this.galleryName = "",
283
+    this.galleryListProvider,
245 284
   }) : super(key: key);
246 285
 
247 286
   @override
@@ -257,6 +296,7 @@ class __BottomWidgetState extends State<_BottomWidget> {
257 296
   Widget build(BuildContext context) {
258 297
     var textStyle = TextStyle(fontSize: 14.0, color: options.textColor);
259 298
     print(MediaQuery.of(context).padding.bottom);
299
+    const textPadding = const EdgeInsets.symmetric(horizontal: 16.0);
260 300
     return Container(
261 301
       color: options.themeColor,
262 302
       child: SafeArea(
@@ -265,9 +305,18 @@ class __BottomWidgetState extends State<_BottomWidget> {
265 305
           height: 44.0,
266 306
           child: Row(
267 307
             children: <Widget>[
268
-              Text(
269
-                widget.galleryName,
270
-                style: textStyle,
308
+              GestureDetector(
309
+                behavior: HitTestBehavior.translucent,
310
+                onTap: _showGallerySelectDialog,
311
+                child: Container(
312
+                  alignment: Alignment.center,
313
+                  height: 44.0,
314
+                  padding: textPadding,
315
+                  child: Text(
316
+                    widget.galleryName,
317
+                    style: textStyle,
318
+                  ),
319
+                ),
271 320
               ),
272 321
               Expanded(
273 322
                 child: Container(),
@@ -279,7 +328,7 @@ class __BottomWidgetState extends State<_BottomWidget> {
279 328
                   i18nProvider.getPreviewText(options, widget.selectedProvider),
280 329
                   style: textStyle,
281 330
                 ),
282
-                padding: const EdgeInsets.symmetric(horizontal: 8.0),
331
+                padding: textPadding,
283 332
               ),
284 333
             ],
285 334
           ),
@@ -287,6 +336,17 @@ class __BottomWidgetState extends State<_BottomWidget> {
287 336
       ),
288 337
     );
289 338
   }
339
+
340
+  void _showGallerySelectDialog() async {
341
+    var result = await showModalBottomSheet(
342
+      context: context,
343
+      builder: (ctx) => ChangeGalleryDialog(
344
+            galleryList: widget.galleryListProvider.galleryPathList,
345
+          ),
346
+    );
347
+
348
+    if (result != null) widget.onGalleryChange?.call(result);
349
+  }
290 350
 }
291 351
 
292 352
 class ImageItem extends StatelessWidget {

+ 2
- 2
pubspec.lock Näytä tiedosto

@@ -211,8 +211,8 @@ packages:
211 211
     dependency: "direct main"
212 212
     description:
213 213
       path: "."
214
-      ref: "0a808b0a537e5203095a6b70aa5c42ca4d5a9c9a"
215
-      resolved-ref: "0a808b0a537e5203095a6b70aa5c42ca4d5a9c9a"
214
+      ref: "2a7004e5de7a50f4a4178d3bb8599bdcfb4c6da4"
215
+      resolved-ref: "2a7004e5de7a50f4a4178d3bb8599bdcfb4c6da4"
216 216
       url: "https://github.com/CaiJingLong/flutter_photo_manager"
217 217
     source: git
218 218
     version: "0.0.1"

+ 1
- 1
pubspec.yaml Näytä tiedosto

@@ -13,7 +13,7 @@ dependencies:
13 13
   photo_manager:
14 14
     git:
15 15
       url: https://github.com/CaiJingLong/flutter_photo_manager
16
-      ref: 0a808b0a537e5203095a6b70aa5c42ca4d5a9c9a
16
+      ref: 2a7004e5de7a50f4a4178d3bb8599bdcfb4c6da4
17 17
 
18 18
 dev_dependencies:
19 19
   flutter_test: