Browse Source

预览页面的修改

Caijinglong 6 years ago
parent
commit
f7c3dc4e78

+ 11
- 0
lib/src/provider/selected_provider.dart View File

30
     return selectedList.remove(entity);
30
     return selectedList.remove(entity);
31
   }
31
   }
32
 
32
 
33
+  void compareAndRemoveEntities(List<ImageEntity> previewSelectedList) {
34
+    var srcList = List.of(selectedList);
35
+    selectedList.clear();
36
+    srcList.forEach((entity) {
37
+      if (previewSelectedList.contains(entity)){
38
+        selectedList.add(entity);
39
+      }
40
+    });
41
+  }
42
+
43
+
33
   void sure();
44
   void sure();
34
 }
45
 }

+ 42
- 11
lib/src/ui/page/photo_main_page.dart View File

101
             options: options,
101
             options: options,
102
             galleryName: currentPath.name,
102
             galleryName: currentPath.name,
103
             onGalleryChange: _onGalleryChange,
103
             onGalleryChange: _onGalleryChange,
104
-            onTapPreview: _onTapPreview,
104
+            onTapPreview: selectedList.isEmpty ? null : _onTapPreview,
105
             selectedProvider: this,
105
             selectedProvider: this,
106
             galleryListProvider: this,
106
             galleryListProvider: this,
107
           ),
107
           ),
173
   Widget _buildItem(BuildContext context, int index) {
173
   Widget _buildItem(BuildContext context, int index) {
174
     var data = list[index];
174
     var data = list[index];
175
     return GestureDetector(
175
     return GestureDetector(
176
-      onTap: () => _onItemClick(data),
176
+      onTap: () => _onItemClick(data, index),
177
       child: Stack(
177
       child: Stack(
178
         children: <Widget>[
178
         children: <Widget>[
179
           ImageItem(
179
           ImageItem(
254
     setState(() {});
254
     setState(() {});
255
   }
255
   }
256
 
256
 
257
-  void _onItemClick(ImageEntity data) {}
258
-
259
   void _onGalleryChange(ImagePathEntity value) {
257
   void _onGalleryChange(ImagePathEntity value) {
260
     _currentPath = value;
258
     _currentPath = value;
261
 
259
 
267
     });
265
     });
268
   }
266
   }
269
 
267
 
270
-  void _onTapPreview() {
268
+  void _onItemClick(ImageEntity data, int index) {
269
+    var result = new PhotoPreviewResult();
271
     Navigator.of(context).push(
270
     Navigator.of(context).push(
271
+      MaterialPageRoute(
272
+        builder: (ctx) {
273
+          return ConfigProvider(
274
+            provider: ConfigProvider.of(context).provider,
275
+            options: options,
276
+            child: PhotoPreviewPage(
277
+              selectedProvider: this,
278
+              list: List.of(list),
279
+              initIndex: index,
280
+              changeProviderOnCheckChange: true,
281
+              result: result,
282
+            ),
283
+          );
284
+        },
285
+      ),
286
+    ).then((v) {
287
+      setState(() {});
288
+    });
289
+  }
290
+
291
+  void _onTapPreview() {
292
+    var result = new PhotoPreviewResult();
293
+    Navigator.of(context)
294
+        .push(
272
       MaterialPageRoute(
295
       MaterialPageRoute(
273
         builder: (ctx) => ConfigProvider(
296
         builder: (ctx) => ConfigProvider(
274
               provider: ConfigProvider.of(context).provider,
297
               provider: ConfigProvider.of(context).provider,
276
               child: PhotoPreviewPage(
299
               child: PhotoPreviewPage(
277
                 selectedProvider: this,
300
                 selectedProvider: this,
278
                 list: List.of(selectedList),
301
                 list: List.of(selectedList),
302
+                changeProviderOnCheckChange: false,
303
+                result: result,
279
               ),
304
               ),
280
             ),
305
             ),
281
       ),
306
       ),
307
+    )
308
+        .then(
309
+      (v) {
310
+        compareAndRemoveEntities(result.previewSelectedList);
311
+      },
282
     );
312
     );
283
   }
313
   }
284
 }
314
 }
319
 
349
 
320
   @override
350
   @override
321
   Widget build(BuildContext context) {
351
   Widget build(BuildContext context) {
322
-    var textStyle = TextStyle(fontSize: 14.0, color: options.textColor);
352
+    var textStyle = TextStyle(fontSize: 14.0);
323
     const textPadding = const EdgeInsets.symmetric(horizontal: 16.0);
353
     const textPadding = const EdgeInsets.symmetric(horizontal: 16.0);
324
     return Container(
354
     return Container(
325
       color: options.themeColor,
355
       color: options.themeColor,
327
         bottom: true,
357
         bottom: true,
328
         top: false,
358
         top: false,
329
         child: Container(
359
         child: Container(
330
-          height: 44.0,
360
+          height: 52.0,
331
           child: Row(
361
           child: Row(
332
             children: <Widget>[
362
             children: <Widget>[
333
               GestureDetector(
363
               GestureDetector(
339
                   padding: textPadding,
369
                   padding: textPadding,
340
                   child: Text(
370
                   child: Text(
341
                     widget.galleryName,
371
                     widget.galleryName,
342
-                    style: textStyle,
372
+                    style: textStyle.copyWith(color: options.textColor),
343
                   ),
373
                   ),
344
                 ),
374
                 ),
345
               ),
375
               ),
346
               Expanded(
376
               Expanded(
347
                 child: Container(),
377
                 child: Container(),
348
               ),
378
               ),
349
-              GestureDetector(
350
-                behavior: HitTestBehavior.translucent,
351
-                onTap: widget.onTapPreview,
379
+              FlatButton(
380
+                onPressed: widget.onTapPreview,
381
+                textColor: options.textColor,
382
+                disabledTextColor: options.disableColor,
352
                 child: Container(
383
                 child: Container(
353
                   height: 44.0,
384
                   height: 44.0,
354
                   alignment: Alignment.center,
385
                   alignment: Alignment.center,

+ 138
- 5
lib/src/ui/page/photo_preview_page.dart View File

5
 import 'package:photo/src/entity/options.dart';
5
 import 'package:photo/src/entity/options.dart';
6
 import 'package:photo/src/provider/config_provider.dart';
6
 import 'package:photo/src/provider/config_provider.dart';
7
 import 'package:photo/src/provider/selected_provider.dart';
7
 import 'package:photo/src/provider/selected_provider.dart';
8
+import 'package:photo/src/ui/page/photo_main_page.dart';
8
 import 'package:photo_manager/photo_manager.dart';
9
 import 'package:photo_manager/photo_manager.dart';
9
 
10
 
10
 class PhotoPreviewPage extends StatefulWidget {
11
 class PhotoPreviewPage extends StatefulWidget {
12
 
13
 
13
   final List<ImageEntity> list;
14
   final List<ImageEntity> list;
14
 
15
 
15
-  const PhotoPreviewPage({Key key, this.selectedProvider, this.list})
16
-      : super(key: key);
16
+  final int initIndex;
17
+
18
+  /// 这个参数是控制在内部点击check后是否实时修改provider状态
19
+  final bool changeProviderOnCheckChange;
20
+
21
+  /// 这里封装了结果
22
+  final PhotoPreviewResult result;
23
+
24
+  const PhotoPreviewPage({
25
+    Key key,
26
+    @required this.selectedProvider,
27
+    @required this.list,
28
+    @required this.changeProviderOnCheckChange,
29
+    @required this.result,
30
+    this.initIndex = 0,
31
+  }) : super(key: key);
17
 
32
 
18
   @override
33
   @override
19
   _PhotoPreviewPageState createState() => _PhotoPreviewPageState();
34
   _PhotoPreviewPageState createState() => _PhotoPreviewPageState();
28
 
43
 
29
   Color get textColor => options.textColor;
44
   Color get textColor => options.textColor;
30
 
45
 
46
+  SelectedProvider get selectedProvider => widget.selectedProvider;
47
+
31
   List<ImageEntity> get list => widget.list;
48
   List<ImageEntity> get list => widget.list;
32
 
49
 
33
   StreamController<int> pageChangeController = StreamController.broadcast();
50
   StreamController<int> pageChangeController = StreamController.broadcast();
34
 
51
 
52
+  Stream<int> get pageStream => pageChangeController.stream;
53
+
54
+  bool get changeProviderOnCheckChange => widget.changeProviderOnCheckChange;
55
+
56
+  List<ImageEntity> get previewSelectedList =>
57
+      widget.result.previewSelectedList;
58
+
59
+  PageController pageController;
60
+
35
   @override
61
   @override
36
   void initState() {
62
   void initState() {
37
     super.initState();
63
     super.initState();
38
     pageChangeController.add(0);
64
     pageChangeController.add(0);
65
+    previewSelectedList.clear();
66
+    previewSelectedList.addAll(selectedProvider.selectedList);
67
+    pageController = PageController(
68
+      initialPage: widget.initIndex,
69
+    );
39
   }
70
   }
40
 
71
 
41
   @override
72
   @override
52
         appBar: AppBar(
83
         appBar: AppBar(
53
           backgroundColor: config.options.themeColor,
84
           backgroundColor: config.options.themeColor,
54
           title: StreamBuilder(
85
           title: StreamBuilder(
55
-            stream: pageChangeController.stream,
56
-            initialData: 0,
86
+            stream: pageStream,
87
+            initialData: widget.initIndex,
57
             builder: (ctx, snap) => Text(
88
             builder: (ctx, snap) => Text(
58
                   "${snap.data + 1}/${widget.list.length}",
89
                   "${snap.data + 1}/${widget.list.length}",
59
                 ),
90
                 ),
60
           ),
91
           ),
61
         ),
92
         ),
62
         body: PageView.builder(
93
         body: PageView.builder(
94
+          controller: pageController,
63
           itemBuilder: _buildItem,
95
           itemBuilder: _buildItem,
64
           itemCount: list.length,
96
           itemCount: list.length,
65
           onPageChanged: _onPageChanged,
97
           onPageChanged: _onPageChanged,
66
         ),
98
         ),
67
         bottomNavigationBar: _buildBottom(),
99
         bottomNavigationBar: _buildBottom(),
100
+        bottomSheet: _buildThumb(),
68
       ),
101
       ),
69
     );
102
     );
70
   }
103
   }
71
 
104
 
72
   Widget _buildBottom() {
105
   Widget _buildBottom() {
73
     return Container(
106
     return Container(
74
-      height: 44.0,
107
+      height: 52.0,
75
       color: themeColor,
108
       color: themeColor,
109
+      child: Row(
110
+        children: <Widget>[
111
+          Expanded(
112
+            child: Container(),
113
+          ),
114
+          _buildCheckbox(),
115
+        ],
116
+      ),
117
+    );
118
+  }
119
+
120
+  Container _buildCheckbox() {
121
+    return Container(
122
+      constraints: BoxConstraints(
123
+        maxWidth: 150.0,
124
+      ),
125
+      child: StreamBuilder<int>(
126
+        builder: (ctx, snapshot) {
127
+          var index = snapshot.data;
128
+          var data = list[index];
129
+          return CheckboxListTile(
130
+            value: previewSelectedList.contains(data),
131
+            onChanged: (bool check) {
132
+              if (changeProviderOnCheckChange) {
133
+                _onChangeProvider(check, index);
134
+              } else {
135
+                _onCheckInOnlyPreview(check, index);
136
+              }
137
+            },
138
+            activeColor: Color.lerp(textColor, themeColor, 0.6),
139
+            title: Text(
140
+              config.provider.getSelectedOptionsText(options),
141
+              textAlign: TextAlign.end,
142
+              style: TextStyle(color: options.textColor),
143
+            ),
144
+          );
145
+        },
146
+        initialData: widget.initIndex,
147
+        stream: pageStream,
148
+      ),
76
     );
149
     );
77
   }
150
   }
78
 
151
 
152
+  /// 仅仅修改预览时的状态,在退出时,再更新provider的顺序,这里无论添加与否不修改顺序
153
+  void _onCheckInOnlyPreview(bool check, int index) {
154
+    var item = list[index];
155
+    if (check) {
156
+      previewSelectedList.add(item);
157
+    } else {
158
+      previewSelectedList.remove(item);
159
+    }
160
+    pageChangeController.add(index);
161
+  }
162
+
163
+  /// 直接修改预览状态,会直接移除item
164
+  void _onChangeProvider(bool check, int index) {
165
+    var item = list[index];
166
+    if (check) {
167
+      if (selectedProvider.addSelectEntity(item)) {
168
+        previewSelectedList.add(item);
169
+      }
170
+    } else {
171
+      selectedProvider.removeSelectEntity(item);
172
+      previewSelectedList.remove(item);
173
+    }
174
+    pageChangeController.add(index);
175
+  }
176
+
79
   Widget _buildItem(BuildContext context, int index) {
177
   Widget _buildItem(BuildContext context, int index) {
80
     var data = list[index];
178
     var data = list[index];
81
     return BigPhotoImage(
179
     return BigPhotoImage(
86
   void _onPageChanged(int value) {
184
   void _onPageChanged(int value) {
87
     pageChangeController.add(value);
185
     pageChangeController.add(value);
88
   }
186
   }
187
+
188
+  Widget _buildThumb() {
189
+    return Container(
190
+      height: 80.0,
191
+      child: ListView.builder(
192
+        itemBuilder: _buildThumbItem,
193
+        itemCount: previewSelectedList.length,
194
+        scrollDirection: Axis.horizontal,
195
+      ),
196
+    );
197
+  }
198
+
199
+  Widget _buildThumbItem(BuildContext context, int index) {
200
+    // todo 这里需要一个遮盖
201
+    var item = previewSelectedList[index];
202
+    return GestureDetector(
203
+      onTap: () => changeSelected(item, index),
204
+      child: Container(
205
+        width: 80.0,
206
+        child: ImageItem(
207
+          themeColor: themeColor,
208
+          entity: item,
209
+        ),
210
+      ),
211
+    );
212
+  }
213
+
214
+  void changeSelected(ImageEntity entity, int index) {
215
+    var itemIndex = list.indexOf(entity);
216
+    if (itemIndex != -1) pageController.jumpToPage(itemIndex);
217
+  }
89
 }
218
 }
90
 
219
 
91
 class BigPhotoImage extends StatefulWidget {
220
 class BigPhotoImage extends StatefulWidget {
121
   @override
250
   @override
122
   bool get wantKeepAlive => true;
251
   bool get wantKeepAlive => true;
123
 }
252
 }
253
+
254
+class PhotoPreviewResult {
255
+  List<ImageEntity> previewSelectedList = [];
256
+}