Browse Source

选择相册修改完毕

Caijinglong 6 years ago
parent
commit
82b3fcc973

+ 2
- 2
lib/photo.dart View File

4
 import 'dart:async';
4
 import 'dart:async';
5
 
5
 
6
 import 'package:photo/src/entity/options.dart';
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
 import 'package:photo/src/provider/i18n_provider.dart';
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
 import 'package:photo_manager/photo_manager.dart';
10
 import 'package:photo_manager/photo_manager.dart';
11
 
11
 
12
 /// A Calculator.
12
 /// A Calculator.

+ 5
- 0
lib/src/provider/gallery_list_provider.dart View File

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 View File

1
 import 'package:photo_manager/photo_manager.dart';
1
 import 'package:photo_manager/photo_manager.dart';
2
 
2
 
3
 abstract class SelectedProvider {
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
   void sure();
33
   void sure();
12
 }
34
 }

+ 35
- 0
lib/src/ui/dialog/change_gallery_dialog.dart View File

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 View File


lib/src/page/photo_main_page.dart → lib/src/ui/page/photo_main_page.dart View File

3
 import 'package:flutter/material.dart';
3
 import 'package:flutter/material.dart';
4
 import 'package:photo/src/engine/lru_cache.dart';
4
 import 'package:photo/src/engine/lru_cache.dart';
5
 import 'package:photo/src/entity/options.dart';
5
 import 'package:photo/src/entity/options.dart';
6
+import 'package:photo/src/provider/gallery_list_provider.dart';
6
 import 'package:photo/src/provider/i18n_provider.dart';
7
 import 'package:photo/src/provider/i18n_provider.dart';
7
 import 'package:photo/src/provider/selected_provider.dart';
8
 import 'package:photo/src/provider/selected_provider.dart';
9
+import 'package:photo/src/ui/dialog/change_gallery_dialog.dart';
8
 import 'package:photo_manager/photo_manager.dart';
10
 import 'package:photo_manager/photo_manager.dart';
9
 
11
 
10
 class PhotoMainPage extends StatefulWidget {
12
 class PhotoMainPage extends StatefulWidget {
17
   _PhotoMainPageState createState() => _PhotoMainPageState();
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
   Options get options => widget.options;
24
   Options get options => widget.options;
22
 
25
 
23
   I18nProvider get i18nProvider => widget.provider;
26
   I18nProvider get i18nProvider => widget.provider;
24
 
27
 
25
-  List<ImageEntity> selectedList = [];
26
-  List<ImageParentPath> pathList = [];
27
-
28
   List<ImageEntity> list = [];
28
   List<ImageEntity> list = [];
29
 
29
 
30
   Color get themeColor => options.themeColor;
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
     if (_currentPath == null) {
35
     if (_currentPath == null) {
36
       return null;
36
       return null;
37
     }
37
     }
38
     return _currentPath;
38
     return _currentPath;
39
   }
39
   }
40
 
40
 
41
-  set currentPath(ImageParentPath value) {
41
+  set currentPath(ImagePathEntity value) {
42
     _currentPath = value;
42
     _currentPath = value;
43
   }
43
   }
44
 
44
 
45
+  GlobalKey scaffoldKey;
46
+  ScrollController scrollController;
47
+
45
   @override
48
   @override
46
   void initState() {
49
   void initState() {
47
     super.initState();
50
     super.initState();
48
     _refreshList();
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
   @override
62
   @override
77
           ),
88
           ),
78
           body: _buildBody(),
89
           body: _buildBody(),
79
           bottomNavigationBar: _BottomWidget(
90
           bottomNavigationBar: _BottomWidget(
91
+            key: scaffoldKey,
80
             provider: i18nProvider,
92
             provider: i18nProvider,
81
             options: options,
93
             options: options,
94
+            galleryName: currentPath.name,
82
             onGalleryChange: _onGalleryChange,
95
             onGalleryChange: _onGalleryChange,
83
             selectedProvider: this,
96
             selectedProvider: this,
97
+            galleryListProvider: this,
84
           ),
98
           ),
85
         ),
99
         ),
86
       ),
100
       ),
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
   void _refreshList() async {
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
     this.list.clear();
142
     this.list.clear();
100
     this.list.addAll(imageList);
143
     this.list.addAll(imageList);
101
     print(list);
144
     print(list);
106
     return Container(
149
     return Container(
107
       color: options.disableColor,
150
       color: options.disableColor,
108
       child: GridView.builder(
151
       child: GridView.builder(
152
+        controller: scrollController,
109
         gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
153
         gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
110
           crossAxisCount: options.rowCount,
154
           crossAxisCount: options.rowCount,
111
           childAspectRatio: options.itemRadio,
155
           childAspectRatio: options.itemRadio,
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
   Widget _buildItem(BuildContext context, int index) {
165
   Widget _buildItem(BuildContext context, int index) {
135
     var data = list[index];
166
     var data = list[index];
136
     return GestureDetector(
167
     return GestureDetector(
208
 
239
 
209
   void changeCheck(bool value, ImageEntity entity) {
240
   void changeCheck(bool value, ImageEntity entity) {
210
     if (value) {
241
     if (value) {
211
-      selectedList.add(entity);
242
+      addSelectEntity(entity);
212
     } else {
243
     } else {
213
-      selectedList.remove(entity);
244
+      removeSelectEntity(entity);
214
     }
245
     }
215
     setState(() {});
246
     setState(() {});
216
   }
247
   }
217
 
248
 
218
-  void sure() {
219
-    Navigator.pop(context, selectedList);
220
-  }
221
-
222
   void _onItemClick(ImageEntity data) {}
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
 class _BottomWidget extends StatefulWidget {
263
 class _BottomWidget extends StatefulWidget {
228
-  final ValueChanged<ImageParentPath> onGalleryChange;
264
+  final ValueChanged<ImagePathEntity> onGalleryChange;
229
 
265
 
230
   final Options options;
266
   final Options options;
231
 
267
 
235
 
271
 
236
   final String galleryName;
272
   final String galleryName;
237
 
273
 
274
+  final GalleryListProvider galleryListProvider;
275
+
238
   const _BottomWidget({
276
   const _BottomWidget({
239
     Key key,
277
     Key key,
240
     this.onGalleryChange,
278
     this.onGalleryChange,
242
     this.provider,
280
     this.provider,
243
     this.selectedProvider,
281
     this.selectedProvider,
244
     this.galleryName = "",
282
     this.galleryName = "",
283
+    this.galleryListProvider,
245
   }) : super(key: key);
284
   }) : super(key: key);
246
 
285
 
247
   @override
286
   @override
257
   Widget build(BuildContext context) {
296
   Widget build(BuildContext context) {
258
     var textStyle = TextStyle(fontSize: 14.0, color: options.textColor);
297
     var textStyle = TextStyle(fontSize: 14.0, color: options.textColor);
259
     print(MediaQuery.of(context).padding.bottom);
298
     print(MediaQuery.of(context).padding.bottom);
299
+    const textPadding = const EdgeInsets.symmetric(horizontal: 16.0);
260
     return Container(
300
     return Container(
261
       color: options.themeColor,
301
       color: options.themeColor,
262
       child: SafeArea(
302
       child: SafeArea(
265
           height: 44.0,
305
           height: 44.0,
266
           child: Row(
306
           child: Row(
267
             children: <Widget>[
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
               Expanded(
321
               Expanded(
273
                 child: Container(),
322
                 child: Container(),
279
                   i18nProvider.getPreviewText(options, widget.selectedProvider),
328
                   i18nProvider.getPreviewText(options, widget.selectedProvider),
280
                   style: textStyle,
329
                   style: textStyle,
281
                 ),
330
                 ),
282
-                padding: const EdgeInsets.symmetric(horizontal: 8.0),
331
+                padding: textPadding,
283
               ),
332
               ),
284
             ],
333
             ],
285
           ),
334
           ),
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
 class ImageItem extends StatelessWidget {
352
 class ImageItem extends StatelessWidget {

+ 2
- 2
pubspec.lock View File

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

+ 1
- 1
pubspec.yaml View File

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